lasaris winter
school
Pokračování lekcí Rustu
dnes vás provází Lukáš Grolig
Na co se dnes podíváme?
- Úvod do GraphQL
- Dotazy
- Mutace
- Architektury s GraphQL
- Juniper
- Integrace do Actix
Fields
Jednoduchý dotaz pro získání objektu s jedním fieldem
{
hero {
name
}
}
Argumenty
{
human(id: "1000") {
name
height(unit: FOOT)
}
}
Pro získání položek na základě parametrů.
Lze použít různé typy a nebo výčet.
Aliasy
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
Fragmenty
{
leftComparison: hero(episode: EMPIRE) {
...comparisonFields
}
rightComparison: hero(episode: JEDI) {
...comparisonFields
}
}
fragment comparisonFields on Character {
name
appearsIn
friends {
name
}
}
Proměnné
query HeroNameAndFriends($episode: Episode) {
hero(episode: $episode) {
name
friends {
name
}
}
}
{
"episode": "JEDI"
}
Defaultní hodnoty
query HeroNameAndFriends($episode: Episode = JEDI) {
hero(episode: $episode) {
name
friends {
name
}
}
}
Direktivy
query Hero($episode: Episode, $withFriends: Boolean!) {
hero(episode: $episode) {
name
friends @include(if: $withFriends) {
name
}
}
}
{
"episode": "JEDI",
"withFriends": false
}
Mutace
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}
{
"ep": "JEDI",
"review": {
"stars": 5,
"commentary": "This is a great movie!"
}
}
Architektury s GQL
GQL nad Rest
Frontend
GQL
S1 Rest
S2 Rest
S3 Rest
SQL Db
NoSql Db
GQL nad DB
Frontend
GQL
SQL Db
Juniper
Cargo.toml
[dependencies]
juniper = "0.14.2"
Integrace s Actix
use std::io;
use std::sync::Arc;
use actix_cors::Cors;
use actix_web::{middleware, web, App, Error, HttpResponse, HttpServer};
use juniper::http::graphiql::graphiql_source;
use juniper::http::GraphQLRequest;
mod schema;
use crate::schema::{create_schema, Schema};
Integrace s Actix
#[actix_web::main]
async fn main() -> io::Result<()> {
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
// Create Juniper schema
let schema = std::sync::Arc::new(create_schema());
// Start http server
HttpServer::new(move || {
App::new()
.data(schema.clone())
.wrap(middleware::Logger::default())
.wrap(
Cors::new()
.allowed_methods(vec!["POST", "GET"])
.supports_credentials()
.max_age(3600)
.finish(),
)
.service(web::resource("/graphql").route(web::post().to(graphql)))
.service(web::resource("/graphiql").route(web::get().to(graphiql)))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Integrace s Actix
async fn graphiql() -> HttpResponse {
let html = graphiql_source("http://127.0.0.1:8080/graphql");
HttpResponse::Ok()
.content_type("text/html; charset=utf-8")
.body(html)
}
async fn graphql(
st: web::Data<Arc<Schema>>,
data: web::Json<GraphQLRequest>,
) -> Result<HttpResponse, Error> {
let user = web::block(move || {
let res = data.execute(&st, &());
Ok::<_, serde_json::error::Error>(serde_json::to_string(&res)?)
})
.await?;
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(user))
}
Enum
use juniper::FieldResult;
use juniper::RootNode;
use juniper::{GraphQLEnum, GraphQLInputObject, GraphQLObject};
#[derive(GraphQLEnum)]
enum Episode {
NewHope,
Empire,
Jedi,
}
Struktura
use juniper::FieldResult;
use juniper::RootNode;
use juniper::{GraphQLEnum, GraphQLInputObject, GraphQLObject};
#[derive(GraphQLObject)]
#[graphql(description = "A humanoid creature in the Star Wars universe")]
struct Human {
id: String,
name: String,
appears_in: Vec<Episode>,
home_planet: String,
}
Struktura
use juniper::FieldResult;
use juniper::RootNode;
use juniper::{GraphQLEnum, GraphQLInputObject, GraphQLObject};
#[derive(GraphQLInputObject)]
#[graphql(description = "A humanoid creature in the Star Wars universe")]
struct NewHuman {
name: String,
appears_in: Vec<Episode>,
home_planet: String,
}
Query root
pub struct QueryRoot;
#[juniper::object]
impl QueryRoot {
fn human(id: String) -> FieldResult<Human> {
Ok(Human {
id: "1234".to_owned(),
name: "Luke".to_owned(),
appears_in: vec![Episode::NewHope],
home_planet: "Mars".to_owned(),
})
}
}
Mutation root
pub struct MutationRoot;
#[juniper::object]
impl MutationRoot {
fn create_human(new_human: NewHuman) -> FieldResult<Human> {
Ok(Human {
id: "1234".to_owned(),
name: new_human.name,
appears_in: new_human.appears_in,
home_planet: new_human.home_planet,
})
}
}
A vytvoření schéma
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;
pub fn create_schema() -> Schema {
Schema::new(QueryRoot {}, MutationRoot {})
}
To je pro dnešek vše.
Dotazy?
Děkuji za pozornost a budu se těšit na příští setkání
RSS: GraphQL & Juniper
By Lukáš Grolig
RSS: GraphQL & Juniper
- 449