query {
posts {
content
author {
username
}
}
}
{
"data": {
"posts": [
{
"content": "Hi!",
"author": {
"username": "jesse"
}
}
]
}
}
| query { |
| posts { |
| content |
| author { |
| username |
| } |
| } |
| } |
| query { |
| posts { |
| content |
| author { |
| username |
| } |
| } |
| } |
| query { |
| posts { |
| content |
| author { |
| username |
| } |
| } |
| } |
| query { |
| posts { |
| content |
| author { |
| username |
| } |
| } |
| } |
# graphql
type Query {
posts: [Post!]!
}
type Post {
id: ID!
author: User!
content: String
}
type User {
id: ID!
username String!
}
struct Query;
struct Post {
id: i32,
author_id: i32,
content: Option<String>,
}
struct User {
id: i32,
username: String,
}
pub struct Query;
#[Object]
impl Query {
async fn posts(
&self, ctx: &Context<'_>
) -> Result<Vec<Post>> {
let posts = sqlx::query_as!(Post,
"select id, author_id, content from posts",
)
.fetch_all(get_db(ctx)?)
.await?;
Ok(posts)
}
}
#[derive(SimpleObject)]
pub struct User {
pub id: i32,
pub username: String,
}
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct Post { |
| pub id: i32, |
| pub content: |
| Option<String>, |
| |
| #[graphql(skip)] |
| pub author_id: i32, |
| } |
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct Post { |
| pub id: i32, |
| pub content: |
| Option<String>, |
| |
| #[graphql(skip)] |
| pub author_id: i32, |
| } |
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct Post { |
| pub id: i32, |
| pub content: |
| Option<String>, |
| |
| #[graphql(skip)] |
| pub author_id: i32, |
| } |
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct Post { |
| pub id: i32, |
| pub content: |
| Option<String>, |
| |
| #[graphql(skip)] |
| pub author_id: i32, |
| } |
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct Post { |
| pub id: i32, |
| pub content: |
| Option<String>, |
| |
| #[graphql(skip)] |
| pub author_id: i32, |
| } |
| #[ComplexObject] |
| impl Post { |
| async fn author( |
| &self, ctx: &Context<'_> |
| ) -> Result<User> { |
| let u = sqlx::query_as!( |
| User, " |
| select id, username from users |
| where id = $1", |
| self.author_id, |
| ) |
| .fetch_one(get_db(ctx)?) |
| .await?; |
| Ok(u) |
| }} |
| #[ComplexObject] |
| impl Post { |
| async fn author( |
| &self, ctx: &Context<'_> |
| ) -> Result<User> { |
| let u = sqlx::query_as!( |
| User, " |
| select id, username from users |
| where id = $1", |
| self.author_id, |
| ) |
| .fetch_one(get_db(ctx)?) |
| .await?; |
| Ok(u) |
| }} |
| #[ComplexObject] |
| impl Post { |
| async fn author( |
| &self, ctx: &Context<'_> |
| ) -> Result<User> { |
| let u = sqlx::query_as!( |
| User, " |
| select id, username from users |
| where id = $1", |
| self.author_id, |
| ) |
| .fetch_one(get_db(ctx)?) |
| .await?; |
| Ok(u) |
| }} |
| #[ComplexObject] |
| impl Post { |
| async fn author( |
| &self, ctx: &Context<'_> |
| ) -> Result<User> { |
| let u = sqlx::query_as!( |
| User, " |
| select id, username from users |
| where id = $1", |
| self.author_id, |
| ) |
| .fetch_one(get_db(ctx)?) |
| .await?; |
| Ok(u) |
| }} |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
| let schema = Schema::build(Query,Mutation,EmptySubscription) |
| .data(db_pool).finish(); |
| |
| let api = async_graphql_warp::graphql(schema).and_then( |
| |(schema, request): ( |
| Schema<Query, Mutation, EmptySubscription>, |
| async_graphql::Request, |
| )| async move { |
| Ok::<_, Infallible>(GraphQLResponse::from( |
| schema.execute(request).await)) |
| }, |
| ); |
| warp::serve(api).run(([0, 0, 0, 0], 8080)).await; |
query {
users {
username
posts {
content
}
}
}
{
"data": {
"users": [
{
"username": "jesse",
"posts": [
{
"content": "Hi!"
}
]
}
]
}
}
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct User { |
| pub id: i32, |
| pub username: String, |
| } |
| #[derive(SimpleObject)] |
| #[graphql(complex)] |
| pub struct User { |
| pub id: i32, |
| pub username: String, |
| } |
#[ComplexObject]
impl User {
async fn posts(
&self, ctx: &Context<'_>
) -> Result<Vec<Post>> {
let posts = sqlx::query_as!(Post, "
select id, author_id, content from posts
where author_id = $1
",
self.id,
)
.fetch_all(get_db(ctx)?).await?;
Ok(posts)
}
}
mutation NewU($name: String!) {
createUser(username: $name) {
id
username
}
}
# variables={ "name": "alice" }
{
"data": {
"createUser": {
"id": 2,
"username": "alice"
}
}
}
| pub struct Mutation; |
| #[Object] |
| impl Mutation { |
| async fn create_user( |
| &self, ctx: &Context<'_>, username: String |
| ) -> Result<User> { |
| let user = sqlx::query_as!(User, " |
| insert into users (username) |
| values ($1) |
| returning id, username", |
| username |
| ) |
| .fetch_one(get_db(ctx)?).await?; |
| Ok(user) |
| }} |
| pub struct Mutation; |
| #[Object] |
| impl Mutation { |
| async fn create_user( |
| &self, ctx: &Context<'_>, username: String |
| ) -> Result<User> { |
| let user = sqlx::query_as!(User, " |
| insert into users (username) |
| values ($1) |
| returning id, username", |
| username |
| ) |
| .fetch_one(get_db(ctx)?).await?; |
| Ok(user) |
| }} |
| pub struct Mutation; |
| #[Object] |
| impl Mutation { |
| async fn create_user( |
| &self, ctx: &Context<'_>, username: String |
| ) -> Result<User> { |
| let user = sqlx::query_as!(User, " |
| insert into users (username) |
| values ($1) |
| returning id, username", |
| username |
| ) |
| .fetch_one(get_db(ctx)?).await?; |
| Ok(user) |
| }} |
| pub struct Mutation; |
| #[Object] |
| impl Mutation { |
| async fn create_user( |
| &self, ctx: &Context<'_>, username: String |
| ) -> Result<User> { |
| let user = sqlx::query_as!(User, " |
| insert into users (username) |
| values ($1) |
| returning id, username", |
| username |
| ) |
| .fetch_one(get_db(ctx)?).await?; |
| Ok(user) |
| }} |
| pub struct Mutation; |
| #[Object] |
| impl Mutation { |
| async fn create_user( |
| &self, ctx: &Context<'_>, username: String |
| ) -> Result<User> { |
| let user = sqlx::query_as!(User, " |
| insert into users (username) |
| values ($1) |
| returning id, username", |
| username |
| ) |
| .fetch_one(get_db(ctx)?).await?; |
| Ok(user) |
| }} |
query {
posts {
content
author {
username
}
}
}
| #[Object] |
| impl Query { |
| async fn posts( |
| &self, ctx: &Context<'_> |
| ) -> Result<Vec<Post>> { |
| if ctx.look_ahead().field("author").exists() { |
| fetch_posts_with_author().await; |
| } else { |
| fetch_posts().await; |
| } |
| } |
| } |
| #[Object] |
| impl Query { |
| async fn posts( |
| &self, ctx: &Context<'_> |
| ) -> Result<Vec<Post>> { |
| if ctx.look_ahead().field("author").exists() { |
| fetch_posts_with_author().await; |
| } else { |
| fetch_posts().await; |
| } |
| } |
| } |
| #[Object] |
| impl Query { |
| async fn posts( |
| &self, ctx: &Context<'_> |
| ) -> Result<Vec<Post>> { |
| if ctx.look_ahead().field("author").exists() { |
| fetch_posts_with_author().await; |
| } else { |
| fetch_posts().await; |
| } |
| } |
| } |
| #[Object] |
| impl Query { |
| async fn posts( |
| &self, ctx: &Context<'_> |
| ) -> Result<Vec<Post>> { |
| if ctx.look_ahead().field("author").exists() { |
| fetch_posts_with_author().await; |
| } else { |
| fetch_posts().await; |
| } |
| } |
| } |
| #[Object] |
| impl Query { |
| async fn posts( |
| &self, ctx: &Context<'_> |
| ) -> Result<Vec<Post>> { |
| if ctx.look_ahead().field("author").exists() { |
| fetch_posts_with_author().await; |
| } else { |
| fetch_posts().await; |
| } |
| } |
| } |
Writing a GraphQL Server in Rust Jesse Hallett < https://sitr.us/ > Sr. Software Engineer at Originate, Inc. Rust, NYC - January 25, 2022 Slides URL: sitr.us/talks/graphql-server-in-rust/