Anthony Giniers
@antogyn
@aginiers
GraphQL part 2 :
wip
https://slides.com/antogyn/graphql
Bastien Chares
@charesbast
@papybastou
GraphQL est un langage de requête pour des données de type graphe
Facebook, GitHub, Pinterest, Coursera, Shopify, Yelp...
- Hiérarchique
- Fortement typé
- Product Centric : Requêtes côté client
- Rétrocompatible
{
"user": {
"id": 123,
"name": "Tony"
}
}
{
user(id: 123) {
id,
name,
}
}
type User {
id: Int
name: String
}
type Query {
user(id: Int): User
}
type User {
id: Int
name: String @deprecated
identity: Identity
}
type Identity {
name: String
}
{
__schema {
types {
name
fields {
name
type {
name
}
}
}
}
}
- Introspectif
{
user(id: 123) {
id,
name,
profilePicture(size: SMALL) {
uri
}
}
}
type Query {
user(id: Int): User
}
type User {
id: Int!
name: String
profilePicture(size: Size): Media
}
type Media {
uri: String
}
enum Size {
SMALL
LARGE
}
Les spécifications sont encodées dans le client
Le langage de requête répond aux besoins des vues et des ingénieurs front-ends
{
user(id: 123) {
id,
name,
}
}
type User {
id: Int
name: String @deprecated
identity: Identity
}
type Identity {
name: String
}
{
user(id: 123) {
id,
identity {
name
}
}
}
type User {
id: Int
name: String
}
{
"__schema": {
"types": [
{
"name": "User",
"fields": [
{
"name": "id",
"type": {
"name": "Int"
}
},
{
"name": "name",
"type": {
"name": "String"
}
},
{
"name": "profilePicture",
"type": {
"name": "Media"
}
}
]
}
...
]
}
}
type User {
id: Int
name: String
profilePicture: Media
}
{
__schema {
types {
name
fields {
name
type {
name
}
}
}
}
}
Et si on codait un réseau social ?
Fastoche non ?
Bah non
Je veux récupérer le dernier post de mon dernier ami
{
me {
friends(last: 1) {
posts(last: 1) {
body
}
}
}
}
{
"me": {
"friends": [{
"posts": [{
"body": "poudre 2 perlimpinpin",
}],
}]
}
}
En REST ?
GET /me/friends/posts?last_friends=1&last_posts=1 ??
{
user(id: 123) {
id,
name,
profilePicture(size: SMALL) {
uri
}
}
}
type Query {
user(id: Int): User
}
type User {
id: Int!
name: String
profilePicture(size: Size): Media
}
type Media {
uri: String
}
enum Size {
SMALL
LARGE
}
query {
user(id: 123) {
id,
name,
profilePicture(size: SMALL) {
uri
}
}
}
{
user(id: 123) {
id,
name,
profilePicture(size: SMALL) {
uri
}
}
}
Les spécifications sont encodées dans le client
Le langage de requête répond aux besoins des vues et des ingénieurs front-ends
{
user(id: 123) {
id,
name,
}
}
type User {
id: Int
name: String @deprecated
identity: Identity
}
type Identity {
name: String
}
{
user(id: 123) {
id,
identity {
name
}
}
}
type User {
id: Int
name: String
}
{
"__schema": {
"types": [
{
"name": "User",
"fields": [
{
"name": "id",
"type": {
"name": "Int"
}
},
{
"name": "name",
"type": {
"name": "String"
}
},
{
"name": "profilePicture",
"type": {
"name": "Media"
}
}
]
}
...
]
}
}
type User {
id: Int
name: String
profilePicture: Media
}
{
__schema {
types {
name
fields {
name
type {
name
}
}
}
}
}
Par exemple :
Le verbe http n'a pas d'importance avec GraphQL (généralement, on utilise du POST)
Cependant, on distingue les Queries des Mutations (équivalents de Query/Command du CQRS)
type Query {
user(id: String!): User
}
type Mutation {
createUser(name: String!): User
}
query {
user(id: 123) {
id,
name
}
}
mutation {
createUser(name: "toto") {
id,
name
}
}
mutation createToto {
createUser(username: "toto") {
id
}
}
mutation createAnyUser($username: String!) {
createUser(username: $username) {
id
}
}
{
"username": "toto"
}
=> Requêtes statiques réutilisables
Variable $username
de type String!
➡ /users/antogyn/repos?sort=pushed&direction=desc&page=1
https://api.github.com/
Récupérer les 5 derniers repos :
La dernière pull request :
➡ /repos/antogyn/xke-graphql-github/pulls&page=1
Rajouter un commentaire :
➡ /repos/antogyn/xke-graphql-github/issues/3/comments
x5 !!!
Bonus points :
- Authentification
- File upload
(petit temps d'adaptation, mais le gain de temps et de confort en vaut la peine)
Questions ?