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

Upgrade juniper to 0.15 (#423)

This commit is contained in:
Yuki Okushi 2021-04-26 20:32:32 +09:00 committed by GitHub
parent ef13969220
commit bb4f97ba41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 137 additions and 50 deletions

117
Cargo.lock generated
View File

@ -705,6 +705,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "ascii"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e"
[[package]] [[package]]
name = "askama" name = "askama"
version = "0.9.0" version = "0.9.0"
@ -1598,6 +1604,19 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "combine"
version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680"
dependencies = [
"ascii",
"byteorder",
"either",
"memchr",
"unreachable",
]
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.4.0" version = "4.4.0"
@ -2362,6 +2381,17 @@ version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
[[package]]
name = "futures-enum"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3422d14de7903a52e9dbc10ae05a7e14445ec61890100e098754e120b2bd7b1e"
dependencies = [
"derive_utils",
"quote",
"syn",
]
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.13" version = "0.3.13"
@ -2540,6 +2570,16 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "graphql-parser"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1abd4ce5247dfc04a03ccde70f87a048458c9356c7e41d21ad8c407b3dde6f2"
dependencies = [
"combine 3.8.1",
"thiserror",
]
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.2.7" version = "0.2.7"
@ -2957,18 +2997,24 @@ dependencies = [
[[package]] [[package]]
name = "juniper" name = "juniper"
version = "0.14.2" version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f662ba51e2fbc3d6dd1ca66be70b44963606a34473156abddcb0351fc6caa668" checksum = "4e1330b4b3b2fe7de256fd08738f7fba28ffa574109c834988c28972f0760dbd"
dependencies = [ dependencies = [
"async-trait",
"bson",
"chrono", "chrono",
"fnv", "fnv",
"futures",
"futures-enum",
"graphql-parser",
"indexmap", "indexmap",
"juniper_codegen", "juniper_codegen",
"serde 1.0.117", "serde 1.0.117",
"serde_derive", "smartstring",
"static_assertions 1.1.0",
"url", "url",
"uuid 0.7.4", "uuid 0.8.1",
] ]
[[package]] [[package]]
@ -3003,10 +3049,11 @@ dependencies = [
[[package]] [[package]]
name = "juniper_codegen" name = "juniper_codegen"
version = "0.14.2" version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40af234d8e971a9d7dda93ffbcc8a44a93f17e69e3067f72ce7a6894c41d51b" checksum = "3faf2a1e2e86cadc6bcc6082d63c73e8eafe6b703a0c5723e585b3d4afcec9cd"
dependencies = [ dependencies = [
"proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@ -3988,6 +4035,30 @@ dependencies = [
"toml", "toml",
] ]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check 0.9.2",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check 0.9.2",
]
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"
@ -4002,9 +4073,9 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.24" version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
@ -4214,7 +4285,7 @@ checksum = "7b94c6247d45d78d24481a5b7aca146f414ec0f5e39e175f294d1876b943eeeb"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes 0.5.6", "bytes 0.5.6",
"combine", "combine 4.4.0",
"dtoa", "dtoa",
"futures-util", "futures-util",
"itoa", "itoa",
@ -4952,6 +5023,15 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85" checksum = "7acad6f34eb9e8a259d3283d1e8c1d34d7415943d4895f65cc73813c7396fc85"
[[package]]
name = "smartstring"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ada87540bf8ef4cf8a1789deb175626829bb59b1fefd816cf7f7f55efcdbae9"
dependencies = [
"static_assertions 1.1.0",
]
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.3.17" version = "0.3.17"
@ -5225,9 +5305,9 @@ checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.53" version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8833e20724c24de12bbaba5ad230ea61c3eafb05b881c7c9d3cfe8638b187e68" checksum = "b9505f307c872bab8eb46f77ae357c8eba1fdacead58ee5a850116b1d7f82883"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -5930,6 +6010,15 @@ dependencies = [
"env_logger 0.8.2", "env_logger 0.8.2",
] ]
[[package]]
name = "unreachable"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
dependencies = [
"void",
]
[[package]] [[package]]
name = "untrusted" name = "untrusted"
version = "0.7.1" version = "0.7.1"
@ -5963,12 +6052,6 @@ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
] ]
[[package]]
name = "uuid"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "0.8.1" version = "0.8.1"

View File

@ -9,7 +9,7 @@ edition = "2018"
[dependencies] [dependencies]
actix-web = "3" actix-web = "3"
juniper = "0.14" juniper = "0.15"
mysql = "17" mysql = "17"
r2d2 = "0.8" r2d2 = "0.8"

View File

@ -2,18 +2,18 @@
GraphQL Implementation in Rust using Actix, Juniper, and Mysql as Database GraphQL Implementation in Rust using Actix, Juniper, and Mysql as Database
# Prerequites ## Prerequisites
- Rust Installed - Rust Installed
- MySql as Database - 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 on there.
# Run ## Run
```sh ```sh
# go to the root dir # go to the root dir
@ -23,6 +23,6 @@ cd juniper-advanced
cargo run cargo run
``` ```
### GraphQL Playground ## GraphQL Playground
http://127.0.0.1:8080/graphiql <http://127.0.0.1:8080/graphiql>

View File

@ -14,7 +14,7 @@ pub async fn graphql(
dbpool: pool.get_ref().to_owned(), dbpool: pool.get_ref().to_owned(),
}; };
let res = web::block(move || { let res = web::block(move || {
let res = data.execute(&schema, &ctx); let res = data.execute_sync(&schema, &ctx);
Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?) Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?)
}) })
.await .await
@ -28,7 +28,7 @@ pub async fn graphql(
pub async fn graphql_playground() -> HttpResponse { pub async fn graphql_playground() -> HttpResponse {
HttpResponse::Ok() HttpResponse::Ok()
.content_type("text/html; charset=utf-8") .content_type("text/html; charset=utf-8")
.body(graphiql_source("/graphql")) .body(graphiql_source("/graphql", None))
} }
pub fn register(config: &mut web::ServiceConfig) { pub fn register(config: &mut web::ServiceConfig) {

View File

@ -12,7 +12,7 @@ pub struct Product {
pub price: f64, pub price: f64,
} }
#[juniper::object(Context = Context)] #[juniper::graphql_object(Context = Context)]
impl Product { impl Product {
fn id(&self) -> &str { fn id(&self) -> &str {
&self.id &self.id
@ -33,7 +33,7 @@ impl Product {
"SELECT * FROM user WHERE id=:id", "SELECT * FROM user WHERE id=:id",
params! {"id" => &self.user_id}, params! {"id" => &self.user_id},
); );
if let Err(err) = user { if let Err(_err) = user {
None None
} else { } else {
let (id, name, email) = from_row(user.unwrap().unwrap()); let (id, name, email) = from_row(user.unwrap().unwrap());

View File

@ -1,4 +1,4 @@
use juniper::{FieldError, FieldResult, RootNode}; use juniper::{EmptySubscription, FieldError, FieldResult, RootNode};
use mysql::{from_row, params, Error as DBError, Row}; use mysql::{from_row, params, Error as DBError, Row};
use crate::db::Pool; use crate::db::Pool;
@ -14,7 +14,7 @@ impl juniper::Context for Context {}
pub struct QueryRoot; pub struct QueryRoot;
#[juniper::object(Context = Context)] #[juniper::graphql_object(Context = Context)]
impl QueryRoot { impl QueryRoot {
#[graphql(description = "List of all users")] #[graphql(description = "List of all users")]
fn users(context: &Context) -> FieldResult<Vec<User>> { fn users(context: &Context) -> FieldResult<Vec<User>> {
@ -24,7 +24,7 @@ impl QueryRoot {
.map(|result| { .map(|result| {
result result
.map(|x| x.unwrap()) .map(|x| x.unwrap())
.map(|mut row| { .map(|row| {
let (id, name, email) = from_row(row); let (id, name, email) = from_row(row);
User { id, name, email } User { id, name, email }
}) })
@ -41,7 +41,7 @@ impl QueryRoot {
let user: Result<Option<Row>, DBError> = let user: Result<Option<Row>, DBError> =
conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id}); conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id});
if let Err(err) = user { if let Err(_err) = user {
return Err(FieldError::new( return Err(FieldError::new(
"User Not Found", "User Not Found",
graphql_value!({ "not_found": "user not found" }), graphql_value!({ "not_found": "user not found" }),
@ -60,7 +60,7 @@ impl QueryRoot {
.map(|result| { .map(|result| {
result result
.map(|x| x.unwrap()) .map(|x| x.unwrap())
.map(|mut row| { .map(|row| {
let (id, user_id, name, price) = from_row(row); let (id, user_id, name, price) = from_row(row);
Product { Product {
id, id,
@ -80,7 +80,7 @@ impl QueryRoot {
let mut conn = context.dbpool.get().unwrap(); let mut conn = context.dbpool.get().unwrap();
let product: Result<Option<Row>, DBError> = let product: Result<Option<Row>, DBError> =
conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id}); conn.first_exec("SELECT * FROM user WHERE id=:id", params! {"id" => id});
if let Err(err) = product { if let Err(_err) = product {
return Err(FieldError::new( return Err(FieldError::new(
"Product Not Found", "Product Not Found",
graphql_value!({ "not_found": "product not found" }), graphql_value!({ "not_found": "product not found" }),
@ -99,7 +99,7 @@ impl QueryRoot {
pub struct MutationRoot; pub struct MutationRoot;
#[juniper::object(Context = Context)] #[juniper::graphql_object(Context = Context)]
impl MutationRoot { impl MutationRoot {
fn create_user(context: &Context, user: UserInput) -> FieldResult<User> { fn create_user(context: &Context, user: UserInput) -> FieldResult<User> {
let mut conn = context.dbpool.get().unwrap(); let mut conn = context.dbpool.get().unwrap();
@ -115,7 +115,7 @@ impl MutationRoot {
); );
match insert { match insert {
Ok(opt_row) => Ok(User { Ok(_opt_row) => Ok(User {
id: new_id, id: new_id,
name: user.name, name: user.name,
email: user.email, email: user.email,
@ -148,7 +148,7 @@ impl MutationRoot {
); );
match insert { match insert {
Ok(opt_row) => Ok(Product { Ok(_opt_row) => Ok(Product {
id: new_id, id: new_id,
user_id: product.user_id, user_id: product.user_id,
name: product.name, name: product.name,
@ -168,8 +168,8 @@ impl MutationRoot {
} }
} }
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>; pub type Schema = RootNode<'static, QueryRoot, MutationRoot, EmptySubscription<Context>>;
pub fn create_schema() -> Schema { pub fn create_schema() -> Schema {
Schema::new(QueryRoot, MutationRoot) Schema::new(QueryRoot, MutationRoot, EmptySubscription::new())
} }

View File

@ -18,7 +18,7 @@ pub struct UserInput {
pub email: String, pub email: String,
} }
#[juniper::object(Context = Context)] #[juniper::graphql_object(Context = Context)]
impl User { impl User {
fn id(&self) -> &str { fn id(&self) -> &str {
&self.id &self.id
@ -42,7 +42,7 @@ impl User {
.map(|result| { .map(|result| {
result result
.map(|x| x.unwrap()) .map(|x| x.unwrap())
.map(|mut row| { .map(|row| {
let (id, user_id, name, price) = from_row(row); let (id, user_id, name, price) = from_row(row);
Product { Product {
id, id,

View File

@ -11,4 +11,4 @@ env_logger = "0.8"
serde = "1.0.103" serde = "1.0.103"
serde_json = "1.0.44" serde_json = "1.0.44"
serde_derive = "1.0.103" serde_derive = "1.0.103"
juniper = "0.14.2" juniper = "0.15"

View File

@ -20,6 +20,7 @@ cargo run (or ``cargo watch -x run``)
[http://127.0.0.1:8080/graphiql](http://127.0.0.1:8080/graphiql) [http://127.0.0.1:8080/graphiql](http://127.0.0.1:8080/graphiql)
_Query example:_ _Query example:_
```graphql ```graphql
{ {
human(id: "1234") { human(id: "1234") {
@ -29,7 +30,9 @@ _Query example:_
} }
} }
``` ```
_Result:_ _Result:_
```json ```json
{ {
"data": { "data": {
@ -58,6 +61,7 @@ mutation {
``` ```
_Result:_ _Result:_
```json ```json
{ {
"data": { "data": {

View File

@ -14,7 +14,7 @@ mod schema;
use crate::schema::{create_schema, Schema}; use crate::schema::{create_schema, Schema};
async fn graphiql() -> HttpResponse { async fn graphiql() -> HttpResponse {
let html = graphiql_source("http://127.0.0.1:8080/graphql"); let html = graphiql_source("http://127.0.0.1:8080/graphql", None);
HttpResponse::Ok() HttpResponse::Ok()
.content_type("text/html; charset=utf-8") .content_type("text/html; charset=utf-8")
.body(html) .body(html)
@ -25,7 +25,7 @@ async fn graphql(
data: web::Json<GraphQLRequest>, data: web::Json<GraphQLRequest>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let user = web::block(move || { let user = web::block(move || {
let res = data.execute(&st, &()); let res = data.execute_sync(&st, &());
Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?) Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?)
}) })
.await?; .await?;

View File

@ -1,5 +1,5 @@
use juniper::FieldResult; use juniper::FieldResult;
use juniper::RootNode; use juniper::{EmptySubscription, RootNode};
#[derive(GraphQLEnum)] #[derive(GraphQLEnum)]
enum Episode { enum Episode {
@ -29,9 +29,9 @@ struct NewHuman {
pub struct QueryRoot; pub struct QueryRoot;
#[juniper::object] #[juniper::graphql_object]
impl QueryRoot { impl QueryRoot {
fn human(id: String) -> FieldResult<Human> { fn human(_id: String) -> FieldResult<Human> {
Ok(Human { Ok(Human {
id: "1234".to_owned(), id: "1234".to_owned(),
name: "Luke".to_owned(), name: "Luke".to_owned(),
@ -43,7 +43,7 @@ impl QueryRoot {
pub struct MutationRoot; pub struct MutationRoot;
#[juniper::object] #[juniper::graphql_object]
impl MutationRoot { impl MutationRoot {
fn create_human(new_human: NewHuman) -> FieldResult<Human> { fn create_human(new_human: NewHuman) -> FieldResult<Human> {
Ok(Human { Ok(Human {
@ -55,8 +55,8 @@ impl MutationRoot {
} }
} }
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>; pub type Schema = RootNode<'static, QueryRoot, MutationRoot, EmptySubscription>;
pub fn create_schema() -> Schema { pub fn create_schema() -> Schema {
Schema::new(QueryRoot {}, MutationRoot {}) Schema::new(QueryRoot {}, MutationRoot {}, EmptySubscription::new())
} }