Skip to content

Commit

Permalink
[EpicsDAO#6] rewrite new module
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasCir committed Oct 7, 2022
1 parent 798797a commit 922679b
Show file tree
Hide file tree
Showing 56 changed files with 2,974 additions and 420 deletions.
2,320 changes: 2,081 additions & 239 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion Cargo.toml
Expand Up @@ -8,6 +8,7 @@ license = "Apache-2.0"
keywords = ["Serverless", "GraphQL", "Async", "PostgreSQL", "Framework"]
homepage = "https://zapp.epics.dev/"
repository = "https://github.com/EpicsDAO/zapp"
rust-version = "1.64.0"

[[bin]]
name = "zapp"
Expand All @@ -17,7 +18,6 @@ path = "src/main.rs"
clap = { version = "3.1.15", features = ["derive", "cargo"] }
serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.81"
serde_yaml = "0.8.24"
console = "0.15.0"
regex = "1.5.6"
chrono = "0.4"
Expand All @@ -27,6 +27,11 @@ quote = "1.0.20"
syn = "1.0.98"
proc-macro2 = { version = "1.0.32", default-features = false }
prettyplease = "0.1.16"
# use sea-orm CLI features directly without running the binary
sea-orm-cli = "0.9.2"

[dev-dependencies]
tempdir = "0.3.7"
walkdir = "2.3.2"
itertools = "0.10.5"

1 change: 1 addition & 0 deletions resources/templates/new/.dockerignore
@@ -0,0 +1 @@
.env
3 changes: 3 additions & 0 deletions resources/templates/new/.gitignore
@@ -0,0 +1,3 @@
/target
.env
keyfile.json
42 changes: 42 additions & 0 deletions resources/templates/new/Cargo.toml
@@ -0,0 +1,42 @@
[package]
name = "{{ app_name }}"
version = "0.1.0"
edition = "2021"
rust-version = "1.64"

[workspace]
members = [".", "entity", "migration"]

[workspace.dependencies]
# graphql base library
async-graphql = { version = "4.0.13", features = ["chrono"] }
# graphql integration for axum web framework
async-graphql-axum = "4.0.13"
# async std lib: used by migration crate
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
# our general web framework
axum = "^0.5.1"
# read dotenv files in main.rs
dotenv = "0.15.0"
# generated local entities
entity = { path = "entity" }
# generated local migrations
migration = { path = "migration" }
# database connection and orm
sea-orm = { version = "0.9.2", features = ["runtime-tokio-native-tls", "sqlx-postgres"] }
# migrate database before startup
sea-orm-migration = "0.9.2"
# asnyc runtime: used by main.rs
tokio = { version = "1.0", features = ["full"] }

[dependencies]
async-graphql = { workspace = true }
async-graphql-axum = { workspace = true }
async-std = { workspace = true }
axum = {workspace = true}
dotenv = { workspace = true }
entity = { workspace = true }
migration = { workspace = true }
sea-orm = { workspace = true }
sea-orm-migration = { workspace = true }
tokio = { workspace = true }
28 changes: 28 additions & 0 deletions resources/templates/new/Dockerfile
@@ -0,0 +1,28 @@
FROM rust:1.64 as builder

# create a new empty bin project such that caching dependencies works
RUN cargo new --bin /usr/src/{{ app_name }}

WORKDIR /usr/src/{{ app_name }}

# cache dependencies
COPY entity entity
COPY migration migration
COPY Cargo.toml Cargo.toml
RUN cargo build --release

# copy source code
COPY src src

# release build
RUN cargo build --release

FROM debian:bullseye-slim

RUN apt-get update \
&& apt-get upgrade \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/src/{{ app_name }}/target/release/{{ app_name }} .

CMD ["./{{ app_name }}"]
19 changes: 19 additions & 0 deletions resources/templates/new/README.md
@@ -0,0 +1,19 @@
# {{ app_name }}

Rust Serverless Framework

## Usage

Run PostgreSQL Docker
```bash
zapp docker psql
```

Run Server
```bash
cargo run
```

Access to GraphQL Playground

`http://localshost:3000/api/graphql`
12 changes: 12 additions & 0 deletions resources/templates/new/entity/Cargo.toml
@@ -0,0 +1,12 @@
[package]
name = "entity"
version = "0.1.0"
edition = "2021"
publish = false

[lib]
name = "entity"
path = "src/lib.rs"

[dependencies]
sea-orm = { workspace = true }
1 change: 1 addition & 0 deletions resources/templates/new/entity/src/lib.rs
@@ -0,0 +1 @@

21 changes: 21 additions & 0 deletions resources/templates/new/src/db.rs
@@ -0,0 +1,21 @@
use dotenv::dotenv;
use sea_orm::DatabaseConnection;

pub struct Database {
pub connection: DatabaseConnection,
}

impl Database {
pub async fn new() -> Self {
dotenv().ok();
let connection = sea_orm::Database::connect(std::env::var("DATABASE_URL").unwrap())
.await
.expect("Could not connect to database");

Database { connection }
}

pub fn get_connection(&self) -> &DatabaseConnection {
&self.connection
}
}
3 changes: 3 additions & 0 deletions resources/templates/new/src/graphql/mod.rs
@@ -0,0 +1,3 @@
pub mod mutation;
pub mod query;
pub mod schema;
7 changes: 7 additions & 0 deletions resources/templates/new/src/graphql/mutation/common.rs
@@ -0,0 +1,7 @@
use async_graphql::SimpleObject;

#[derive(SimpleObject)]
pub struct DeleteResult {
pub success: bool,
pub rows_affected: u64,
}
4 changes: 4 additions & 0 deletions resources/templates/new/src/graphql/mutation/mod.rs
@@ -0,0 +1,4 @@
pub mod common;

#[derive(async_graphql::MergedObject, Default)]
pub struct Mutation();
2 changes: 2 additions & 0 deletions resources/templates/new/src/graphql/query/mod.rs
@@ -0,0 +1,2 @@
#[derive(async_graphql::MergedObject, Default)]
pub struct Query();
20 changes: 20 additions & 0 deletions resources/templates/new/src/graphql/schema.rs
@@ -0,0 +1,20 @@
use async_graphql::{EmptySubscription, Schema};
use migration::{Migrator, MigratorTrait};

use crate::{
db::Database,
graphql::{mutation::Mutation, query::Query},
};

pub type ZappSchema = Schema<Query, Mutation, EmptySubscription>;

/// Builds the GraphQL Schema, attaching the Database to the context
pub async fn build_schema() -> ZappSchema {
let db = Database::new().await;

Migrator::up(db.get_connection(), None).await.unwrap();

Schema::build(Query::default(), Mutation::default(), EmptySubscription)
.data(db)
.finish()
}
48 changes: 48 additions & 0 deletions resources/templates/new/src/main.rs
@@ -0,0 +1,48 @@
mod db;
mod graphql;

use async_graphql::http::{playground_source, GraphQLPlaygroundConfig};
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
use axum::{
extract::Extension,
response::{Html, IntoResponse},
routing::get,
Router,
};
use graphql::schema::{build_schema, ZappSchema};
use std::env;

#[cfg(debug_assertions)]
use dotenv::dotenv;

async fn graphql_handler(schema: Extension<ZappSchema>, req: GraphQLRequest) -> GraphQLResponse {
schema.execute(req.into_inner()).await.into()
}

async fn graphql_playground() -> impl IntoResponse {
Html(playground_source(GraphQLPlaygroundConfig::new(
"/api/graphql",
)))
}

#[tokio::main]
async fn main() {
#[cfg(debug_assertions)]
dotenv().ok();
let port = env::var("PORT").expect("PORT must be set.");
let schema = build_schema().await;

let app = Router::new()
.route(
"/api/graphql",
get(graphql_playground).post(graphql_handler),
)
.layer(Extension(schema));

println!("Playground: http://localhost:{}/api/graphql", port);

axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
12 changes: 2 additions & 10 deletions src/docker/process.rs
Expand Up @@ -2,10 +2,9 @@ use crate::style_print::*;
use std::process::Command;
use std::str;


pub fn process_psql_docker() {
create_docker_network();
process_docker_psql("zapp-psql");
process_docker_psql();
}

pub fn process_docker_build(project_id: &str, service_name: &str, gcr_region: &str) {
Expand Down Expand Up @@ -38,25 +37,18 @@ pub fn process_docker_restart() {
let _output2 = Command::new("zapp").args(&["docker", "psql"]).output();
}

fn process_docker_psql(service_name: &str) {
let underscored_name = service_name.to_string().replace("-", "_");
let container_name = String::from(service_name) + "-psql";
let db_name = String::from("POSTGRES_DB=") + &underscored_name + "_db";
fn process_docker_psql() {
let output = Command::new("docker")
.args(&[
"run",
"--rm",
"-d",
"--name",
&container_name,
"-p",
"5432:5432",
"-e",
"POSTGRES_USER=postgres",
"-e",
"POSTGRES_PASSWORD=postgres",
"-e",
&db_name,
"--network=zapp",
"postgres:14.3-alpine",
])
Expand Down
1 change: 1 addition & 0 deletions src/g/entity/creation.rs
Expand Up @@ -22,6 +22,7 @@ pub(super) fn create_entity(model: &str, entity_src_dir: &Path) {

fn create_model_tokens(model_str: &str) -> TokenStream {
let model = format_ident!("{}", model_str);
#[allow(unused_variables)]
let cap_model = format_ident!("{}", to_upper_camel(model_str));

quote! {
Expand Down
2 changes: 1 addition & 1 deletion src/g/migration/creation.rs
@@ -1,4 +1,4 @@
use crate::g::{emit_generated_code, read_dir};
use crate::g::emit_generated_code;
use crate::style_print::log_success;
use chrono::NaiveDateTime;
use proc_macro2::TokenStream;
Expand Down
2 changes: 1 addition & 1 deletion src/g/mod.rs
Expand Up @@ -49,7 +49,7 @@ pub(self) fn emit_generated_code(
file_path
}

pub fn process_g(model: &str, dt: NaiveDateTime, gen_path: &Path) {
pub fn handle_g(model: &str, dt: NaiveDateTime, gen_path: &Path) {
process_entity(model, gen_path);
process_migration(model, dt, gen_path);
process_graphql_mutation(model, gen_path);
Expand Down

0 comments on commit 922679b

Please sign in to comment.