1
0
mirror of https://github.com/actix/examples synced 2024-11-23 14:31:07 +01:00

update graphql advanced example

This commit is contained in:
Rob Ede 2022-02-17 20:59:04 +00:00
parent 7a3fc52a70
commit e0888cd255
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
9 changed files with 72 additions and 76 deletions

29
Cargo.lock generated
View File

@ -168,18 +168,6 @@ dependencies = [
"trust-dns-resolver 0.19.7", "trust-dns-resolver 0.19.7",
] ]
[[package]]
name = "actix-cors"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3e5c769e4d332bfad27f11b8139b5818c4bbddb02c385b8f16344d93ff1a8eb"
dependencies = [
"actix-service 1.0.6",
"actix-web 3.3.3",
"derive_more",
"futures-util",
]
[[package]] [[package]]
name = "actix-cors" name = "actix-cors"
version = "0.6.0-beta.10" version = "0.6.0-beta.10"
@ -845,7 +833,7 @@ dependencies = [
name = "actix-web-cors" name = "actix-web-cors"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"actix-cors 0.6.0-beta.10", "actix-cors",
"actix-web 4.0.0-rc.3", "actix-web 4.0.0-rc.3",
"env_logger 0.9.0", "env_logger 0.9.0",
"futures", "futures",
@ -3340,9 +3328,11 @@ dependencies = [
name = "juniper-advanced" name = "juniper-advanced"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"actix-web 3.3.3", "actix-cors",
"actix-web 4.0.0-rc.3",
"actix-web-lab",
"dotenv", "dotenv",
"env_logger 0.8.4", "env_logger 0.9.0",
"juniper", "juniper",
"log", "log",
"mysql", "mysql",
@ -3357,12 +3347,13 @@ dependencies = [
name = "juniper-example" name = "juniper-example"
version = "1.0.0" version = "1.0.0"
dependencies = [ dependencies = [
"actix-cors 0.4.1", "actix-cors",
"actix-web 3.3.3", "actix-web 4.0.0-rc.3",
"env_logger 0.8.4", "actix-web-lab",
"env_logger 0.9.0",
"juniper", "juniper",
"log",
"serde 1.0.136", "serde 1.0.136",
"serde_derive",
"serde_json", "serde_json",
] ]

View File

@ -4,7 +4,7 @@ version = "1.0.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
actix-web = {version = "4.0.0-beta.21", features = ["rustls"]} actix-web = { version = "4.0.0-beta.21", features = ["rustls"] }
rustls = "0.20.2" rustls = "0.20.2"
rustls-pemfile = "0.2.1" # these are now in an external library rustls-pemfile = "0.2.1"
futures = "0.3" futures = "0.3"

View File

@ -1 +1 @@
DATABASE_URL=mysql://user:password@127.0.0.1/dbname DATABASE_URL=mysql://user:password@127.0.0.1/graphql_testing

View File

@ -3,20 +3,20 @@ name = "juniper-advanced"
version = "1.0.0" version = "1.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
actix-web = "3" actix-web = "4.0.0-rc.3"
actix-web-lab = "0.10"
actix-cors = "0.6.0-beta.10"
juniper = "0.15" juniper = "0.15"
mysql = "17" mysql = "17"
r2d2 = "0.8" r2d2 = "0.8"
r2d2_mysql = "17.0" r2d2_mysql = "17"
dotenv = "0.15" dotenv = "0.15"
env_logger = "0.8" env_logger = "0.9"
log = "0.4" log = "0.4"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1.0" serde_json = "1"
uuid = { version = "0.8", features = ["serde", "v4"] } uuid = { version = "0.8", features = ["serde", "v4"] }

View File

@ -1,28 +1,34 @@
# juniper-advanced # juniper-advanced
GraphQL Implementation in Rust using Actix, Juniper, and Mysql as Database GraphQL Implementation in Rust using Actix, Juniper, and MySQL as Database
## Prerequisites ## Prerequisites
- Rust Installed - MySQL server
- MySql as Database
## Database Configuration ## Database Configuration
Create a new database for this project, and import the existing database schema has been provided named ```mysql-schema.sql```. Create a new database for this project, and import the existing database schema has been provided named `mysql-schema.sql`.
Create ```.env``` file on the root directory of this project and set environment variable named ```DATABASE_URL```, the example file has been provided named ```.env.example```, you can see the format on there. Create `.env` file on the root directory of this project and set environment variable named `DATABASE_URL`, the example file has been provided named `.env.example`, you can see the format in there.
## Run ```sh
cat mysql-schema.sql | mysql -u root -D graphql_testing
```
## Usage
```sh ```sh
# go to the root dir
cd graphql/juniper-advanced cd graphql/juniper-advanced
cp .env.example .env
# edit .env and insert your DB credentials
cargo run cargo run
``` ```
## GraphQL Playground ## GraphQL Playground
GraphQL provides its own documentation. Click the "docs" link in the top right of the GraphiQL UI to see what types of queries and mutations are possible.
```
http://localhost:8080/graphiql
``` ```
http://127.0.0.1:8080/graphiql
```

View File

@ -1,6 +1,6 @@
-- MySQL dump 10.13 Distrib 8.0.16, for osx10.14 (x86_64) -- MySQL dump 10.13 Distrib 8.0.16, for osx10.14 (x86_64)
-- --
-- Host: 127.0.0.1 Database: rust_graphql -- Host: 127.0.0.1 Database: graphql_testing
-- ------------------------------------------------------ -- ------------------------------------------------------
-- Server version 8.0.15 -- Server version 8.0.15

View File

@ -1,10 +1,14 @@
use actix_web::{web, Error, HttpResponse}; use actix_web::{get, route, web, Error, HttpResponse, Responder};
use juniper::http::graphiql::graphiql_source; use actix_web_lab::respond::Html;
use juniper::http::GraphQLRequest; use juniper::http::{graphiql::graphiql_source, GraphQLRequest};
use crate::db::Pool; use crate::{
use crate::schemas::root::{create_schema, Context, Schema}; db::Pool,
schemas::root::{create_schema, Context, Schema},
};
/// GraphQL endpoint
#[route("/graphql", method = "GET", method = "POST")]
pub async fn graphql( pub async fn graphql(
pool: web::Data<Pool>, pool: web::Data<Pool>,
schema: web::Data<Schema>, schema: web::Data<Schema>,
@ -13,27 +17,21 @@ pub async fn graphql(
let ctx = Context { let ctx = Context {
dbpool: pool.get_ref().to_owned(), dbpool: pool.get_ref().to_owned(),
}; };
let res = web::block(move || {
let res = data.execute_sync(&schema, &ctx);
serde_json::to_string(&res)
})
.await
.map_err(Error::from)?;
Ok(HttpResponse::Ok() let res = data.execute(&schema, &ctx).await;
.content_type("application/json")
.body(res)) Ok(HttpResponse::Ok().json(res))
} }
pub async fn graphql_playground() -> HttpResponse { /// GraphiQL UI
HttpResponse::Ok() #[get("/graphiql")]
.content_type("text/html; charset=utf-8") async fn graphql_playground() -> impl Responder {
.body(graphiql_source("/graphql", None)) Html(graphiql_source("/graphql", None))
} }
pub fn register(config: &mut web::ServiceConfig) { pub fn register(config: &mut web::ServiceConfig) {
config config
.data(create_schema()) .app_data(web::Data::new(create_schema()))
.route("/graphql", web::post().to(graphql)) .service(graphql)
.route("/graphiql", web::get().to(graphql_playground)); .service(graphql_playground);
} }

View File

@ -1,32 +1,33 @@
#[macro_use] #[macro_use]
extern crate juniper; extern crate juniper;
extern crate r2d2;
extern crate r2d2_mysql;
extern crate serde_json;
use actix_web::{middleware, web, App, HttpServer}; use actix_cors::Cors;
use actix_web::{middleware::Logger, web::Data, App, HttpServer};
use crate::db::get_db_pool;
use crate::handlers::register;
mod db; mod db;
mod handlers; mod handlers;
mod schemas; mod schemas;
use self::{db::get_db_pool, handlers::register};
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok(); dotenv::dotenv().ok();
std::env::set_var("RUST_LOG", "actix_web=info,info"); env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
env_logger::init();
let pool = get_db_pool(); let pool = get_db_pool();
log::info!("starting HTTP server on port 8080");
log::info!("the GraphiQL interface HTTP server at http://localhost:8080/graphiql");
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
.data(pool.clone()) .app_data(Data::new(pool.clone()))
.wrap(middleware::Logger::default())
.configure(register) .configure(register)
.default_service(web::to(|| async { "404" })) .wrap(Cors::permissive())
.wrap(Logger::default())
}) })
.workers(2)
.bind(("127.0.0.1", 8080))? .bind(("127.0.0.1", 8080))?
.run() .run()
.await .await

View File

@ -17,9 +17,9 @@ mod schema;
use crate::schema::{create_schema, Schema}; use crate::schema::{create_schema, Schema};
/// GraphiQL UI /// GraphiQL playground UI
#[get("/graphiql")] #[get("/graphiql")]
async fn graphiql() -> impl Responder { async fn graphql_playground() -> impl Responder {
Html(graphiql_source("/graphql", None)) Html(graphiql_source("/graphql", None))
} }
@ -47,7 +47,7 @@ async fn main() -> io::Result<()> {
App::new() App::new()
.app_data(Data::from(schema.clone())) .app_data(Data::from(schema.clone()))
.service(graphql) .service(graphql)
.service(graphiql) .service(graphql_playground)
// the graphiql UI requires CORS to be enabled // the graphiql UI requires CORS to be enabled
.wrap(Cors::permissive()) .wrap(Cors::permissive())
.wrap(middleware::Logger::default()) .wrap(middleware::Logger::default())