Workshop - U Lékaře

API Orchestrace

GraphQL

Silně typovaný jazyk pro definici API schématu

Slouží naráz jako:

  • Popis schématu
  • Programová definice
  • Dokumentace

Schema example

Query example and result

type Query {
  songs: [Song!]!
}

type Song {
  id: ID!
  name: String!
  description: String!
  ...
}
query {
  songs {
    name
  }
}
{
  "data": {
    "songs": [
      {
        "name": "Bad Dream Baby"
      },
      ...
    ]
  }
}

Schéma a terminologie

  • typy - základní stavební kámen
  • fieldy - každý typ má své
  • inputy - vstupní parametry
  • skaláry - základní datové typy (např. ID, Int, Float, String)
  • direktivy - pomocné konstrukce (meta programování)
  • fragmenty - sdílení částí dotazů

Základní operace:

  • Query
  • Mutace
  • Subscription

Query

scalar NonNegativeInt

type Query

# -----------------------------------

extend type Query {
    song(id: ID!): Song!
    songs: [Song!]!
    search(name: String!): [Song!]!
}

# -----------------------------------

type Song {
    id: ID!
    name: String!
    artist: String!
    cover: String!
    description: String!
    listens: NonNegativeInt!
    tags: [Tag!]!
    audio: String
    isLiked: Boolean
    comments: [Comment!]
}
type Tag {
    value: String!
    isImportant: Boolean
}

type Comment {
    user: User!
    text: String!
}

# -----------------------------------

interface User {
    name: String!
    avatar: String!
    isArtist: Boolean
}

# -----------------------------------

type RegularUser implements User {
    name: String!
    avatar: String!
    isArtist: Boolean
}

type ArtistUser implements User {
    name: String!
    avatar: String!
    isArtist: Boolean
}

Mutace

type Mutation

# -----------------------------------

extend type Mutation {
    setLike(songId: ID!, like: Toggle!): Song!
    addComment(songId: ID!, comment: CommentInput!): Song!
}

# -----------------------------------

enum Toggle {
    ADD
    REMOVE
}

# -----------------------------------

input CommentInput {
    user: UserInput!
    text: String!
}

input UserInput {
    name: String!
    avatar: String!
    isArtist: Boolean
}

Subscription

directive @songExists on FIELD_DEFINITION

# ---------------------------------------------------------

type Subscription

# -----------------------------------

extend type Subscription {
    commentAdded(songId: ID!): Comment! @songExists
    listens(songId: ID!): NonNegativeInt! @songExists
}

Fragment

query AllSongs {
    songs {
        name
        artist
        cover
        description
        listens
        tags {
            value
            isImportant
        }
        audio
        isLiked
        comments {
            user {
                name
                avatar
                isArtist
            }
            text
        }
    }
}
fragment SongFragment on Song {
    name
    artist
    cover
    description
    listens
    tags {
        value
        isImportant
    }
    audio
    isLiked
    comments {
        user {
            name
            avatar
            isArtist
        }
        text
    }
}
query AllSongs {
    songs {
        ...SongFragment
    }
}

Porovnání s REST

  • Může být více efektivní objem přenesených dat
    • Jeden dotaz na server pro všechny potřebná data
  • Více se tak přizpůsobuje potřebám různých klientů
    • Ptej se jen na to, co opravdu potřebuješ
    • Získej data naráz v rámci jediného requestu
  • Přenos souborů
    • Obecně zeměřené na textová data
  • Řešení chybových stavů přes HTTP
    • Možnost adopce více protokolů
  • Adaptace průmyslem
    • Existující knihovny, nástroje, standardy atd.

Možnosti kombinace GraphQL s REST API přináší další výhody

GraphQL na serveru

Platforma a tooling

GraphQL MVC

*What is your view in REST?

Resolvery

  • Resolver je propojení mezi schématem a mezi datovými zdroji
  • Teoreticky nepotřebuji nic jiného než schéma a resolver
    • Z pohledu architektury je ale lepší mít samostatnou vrstvu datových zdrojů
  • Neměli by řešit obecnou business logiku
    • Jejich cílem definice logiky resolvování dat pro schéma

parent

argumenty

kontext

+ graphql query info

Data sources

Definice zdrojů dat pro aplikaci a její schéma

  • Typicky se může být:
    • HTTP klient => jiné REST API
    • Navázáni na databázi
    • Orchestrace služeb třetích stran

Jejich programová logika a pojetí jsou velmi flexibilní dle potřeby

Další přidaná hodnota

  • Rovnou navrhuji modely a jejich vztahy (graf)
    • Např. uživatel má přátele což jsou další uživatelé a ti mohou mít další přátele
    • Šetříme pak requesty a potenciálně jsme rychlejší
  • Chytré cachování
  • Mnohem jednodušší implementace frontendu
    • Např. nemusím handlovat stav
  • Nemusím psát dokumentaci
    • Dokumentace automaticky vychází z implementace 🥰
  • Možnost brát aplikační datové typy přímo z GraphQL schématu

Caching

  • Cachování přímo na CDN / Key-Value store (např. Redis)
    • Requesty nedojdou ani na server 🥳

N+1 problém

Problém na který se v GraphQL může snadno narazit

 

Má však hned několik řešení:

  • Dataloader
  • Podmíněný JOIN na základě query (SQL)
type Book {
    author: Author!
}

type Author {
    name: String!
}

type Query {
    getAllBooks: [Book!]!
}

Testování

  • Stejně jednoduché jako u REST API
    • Stačí zavolat dotaz a validovat odpověď
    • Zde je plus nápověda při tvorbě dotazů 😉
  • Integrační testy pomocí Apollo Server Testing
  • Testy pomocí nástrojů jako Postman

Orchestrace API

  • Cílem je vytvořit flexibilní API Gateway
    • Kombinuje možnosti starých i nových služeb
    • Mixuje a obaluje REST s GraphQL pro pohodlné použítí na frontendu
    • Umožnuje plynulejší přechod na nové služby bez většího výpadku

API Gateway

  • Softwarová gateway oddělující celý backend
  • V základu REST API s určitými endpointy pro GraphQL
  • GraphQL může interně volat již existující REST endpointy
  • Může zajišťovat i authentikaci do celé aplikace
  • Musí být spolehlivá a škálovatelná

Návrh orchestrace

*Pilotní ukázka bez větších detailů

**Zapojení FE ukáže ještě Radim

Diskuze

Projekt Institute H21

  • Nová verze hlasovací platformy
  • Primárně pro statistické porovnání hlasovacích metod
  • Cílem je především propagovat Janečkovu hlasovací metodu
  • Serverless platforma na Google Cloud Platform (GCP)
  • První verze cílena na hlasování o participativním rozpočtu New Yorku
  • Škálovatelnost, stabilita, přijatelná provozní cena
  • Použití GraphQL jako hlavního API

IH21 - Architektura

Projekt Abaku

  • Vzdělávací matematická hra primárně pro základní školy
  • "Scrabble s čísly"
  • Důraz na komunikaci (chat) a multiplayer
  • Možnost hrát i proti robotovi s "umělou inteligencí"
  • Serverless aplikace postavená na AWS
  • Důraz na škálovatelnost, realtime komunikaci a nízkou provozní cenu
  • Použití GraphQL jako hlavního API
  • Technologická výzva k zajistění real-time komunikace bez stálé běžícího serveru

Abaku - Architektura

* CloudFormation export

** Game Service

Otázky?

U Lékaře - GraphQL & API Orchestrace

By Jindřich Máca

U Lékaře - GraphQL & API Orchestrace

  • 482