Čeština

Naučte se škálovatelné návrhové vzory pro schémata GraphQL k tvorbě robustních a udržovatelných API pro globální publikum. Zvládněte schema stitching, federaci a modularizaci.

Návrh schématu GraphQL: Škálovatelné vzory pro globální API

GraphQL se stal silnou alternativou k tradičním REST API a nabízí klientům flexibilitu vyžádat si přesně ta data, která potřebují. S rostoucí složitostí a rozsahem vašeho GraphQL API – zejména pokud slouží globálnímu publiku s různými datovými požadavky – se však pečlivý návrh schématu stává klíčovým pro udržovatelnost, škálovatelnost a výkon. Tento článek zkoumá několik škálovatelných návrhových vzorů pro schémata GraphQL, které vám pomohou vytvořit robustní API schopná zvládnout požadavky globální aplikace.

Důležitost škálovatelného návrhu schématu

Dobře navržené schéma GraphQL je základem úspěšného API. Určuje, jak mohou klienti interagovat s vašimi daty a službami. Špatný návrh schématu může vést k řadě problémů, včetně:

U globálních aplikací jsou tyto problémy ještě výraznější. Různé regiony mohou mít odlišné datové požadavky, regulační omezení a očekávání ohledně výkonu. Škálovatelný návrh schématu vám umožní tyto výzvy efektivně řešit.

Klíčové principy škálovatelného návrhu schématu

Než se ponoříme do konkrétních vzorů, nastíníme si několik klíčových principů, kterými by se měl váš návrh schématu řídit:

Škálovatelné návrhové vzory pro schémata

Zde je několik škálovatelných návrhových vzorů, které můžete použít k vytvoření robustních GraphQL API:

1. Schema Stitching (Spojování schémat)

Schema stitching umožňuje zkombinovat více GraphQL API do jednoho, sjednoceného schématu. To je zvláště užitečné, když máte různé týmy nebo služby zodpovědné za různé části vašich dat. Je to jako mít několik mini-API a spojit je dohromady prostřednictvím 'gateway' API.

Jak to funguje:

  1. Každý tým nebo služba vystavuje své vlastní GraphQL API s vlastním schématem.
  2. Centrální gateway služba používá nástroje pro schema stitching (jako Apollo Federation nebo GraphQL Mesh) k sloučení těchto schémat do jednoho, sjednoceného schématu.
  3. Klienti komunikují s gateway službou, která směruje požadavky na příslušná podkladová API.

Příklad:

Představte si e-commerce platformu se samostatnými API pro produkty, uživatele a objednávky. Každé API má své vlastní schéma:

  
    # Products API
    type Product {
      id: ID!
      name: String!
      price: Float!
    }

    type Query {
      product(id: ID!): Product
    }

    # Users API
    type User {
      id: ID!
      name: String!
      email: String!
    }

    type Query {
      user(id: ID!): User
    }

    # Orders API
    type Order {
      id: ID!
      userId: ID!
      productId: ID!
      quantity: Int!
    }

    type Query {
      order(id: ID!): Order
    }
  

Gateway služba může tato schémata spojit a vytvořit tak sjednocené schéma:

  
    type Product {
      id: ID!
      name: String!
      price: Float!
    }

    type User {
      id: ID!
      name: String!
      email: String!
    }

    type Order {
      id: ID!
      user: User! @relation(field: "userId")
      product: Product! @relation(field: "productId")
      quantity: Int!
    }

    type Query {
      product(id: ID!): Product
      user(id: ID!): User
      order(id: ID!): Order
    }
  

Všimněte si, jak typ Order nyní obsahuje reference na User a Product, přestože jsou tyto typy definovány v samostatných API. Toho je dosaženo pomocí direktiv pro schema stitching (jako @relation v tomto příkladu).

Výhody:

Zvažte:

2. Schema Federation (Federace schémat)

Federace schémat je evolucí spojování schémat (schema stitching), navržená tak, aby řešila některé jeho nedostatky. Poskytuje deklarativnější a standardizovanější přístup ke skládání schémat GraphQL.

Jak to funguje:

  1. Každá služba vystavuje GraphQL API a anotuje své schéma federačními direktivami (např. @key, @extends, @external).
  2. Centrální gateway služba (používající Apollo Federation) používá tyto direktivy k vytvoření supergrafu – reprezentace celého federovaného schématu.
  3. Gateway služba používá supergraf ke směrování požadavků na příslušné podkladové služby a k řešení závislostí.

Příklad:

Při použití stejného příkladu z e-commerce by federovaná schémata mohla vypadat takto:

  
    # Products API
    type Product @key(fields: "id") {
      id: ID!
      name: String!
      price: Float!
    }

    type Query {
      product(id: ID!): Product
    }

    # Users API
    type User @key(fields: "id") {
      id: ID!
      name: String!
      email: String!
    }

    type Query {
      user(id: ID!): User
    }

    # Orders API
    type Order {
      id: ID!
      userId: ID!
      productId: ID!
      quantity: Int!
      user: User! @requires(fields: "userId")
      product: Product! @requires(fields: "productId")
    }

    extend type Query {
      order(id: ID!): Order
    }
  

Všimněte si použití federačních direktiv:

Výhody:

Zvažte:

3. Modulární návrh schématu

Modulární návrh schématu zahrnuje rozdělení velkého, monolitického schématu na menší, lépe spravovatelné moduly. To usnadňuje pochopení, úpravy a opětovné použití jednotlivých částí vašeho API, i bez použití federovaných schémat.

Jak to funguje:

  • Identifikujte logické hranice ve vašem schématu (např. uživatelé, produkty, objednávky).
  • Vytvořte samostatné moduly pro každou hranici, které definují typy, dotazy a mutace související s touto hranicí.
  • Použijte mechanismy importu/exportu (v závislosti na implementaci vašeho GraphQL serveru) ke spojení modulů do jednoho, sjednoceného schématu.
  • Příklad (s použitím JavaScript/Node.js):

    Vytvořte samostatné soubory pro každý modul:

      
        // users.graphql
        type User {
          id: ID!
          name: String!
          email: String!
        }
    
        type Query {
          user(id: ID!): User
        }
    
        // products.graphql
        type Product {
          id: ID!
          name: String!
          price: Float!
        }
    
        type Query {
          product(id: ID!): Product
        }
      
    

    Poté je zkombinujte ve svém hlavním souboru se schématem:

      
        // schema.js
        const { makeExecutableSchema } = require('graphql-tools');
        const { typeDefs: userTypeDefs, resolvers: userResolvers } = require('./users');
        const { typeDefs: productTypeDefs, resolvers: productResolvers } = require('./products');
    
        const typeDefs = [
          userTypeDefs,
          productTypeDefs,
          ""
        ];
    
        const resolvers = {
          Query: {
            ...userResolvers.Query,
            ...productResolvers.Query,
          }
        };
    
        const schema = makeExecutableSchema({
          typeDefs,
          resolvers,
        });
    
        module.exports = schema;
      
    

    Výhody:

    Zvažte:

    4. Typy Interface a Union

    Typy Interface a Union vám umožňují definovat abstraktní typy, které mohou být implementovány více konkrétními typy. To je užitečné pro reprezentaci polymorfních dat – dat, která mohou nabývat různých forem v závislosti na kontextu.

    Jak to funguje:

    Příklad:

      
        interface Node {
          id: ID!
        }
    
        type User implements Node {
          id: ID!
          name: String!
          email: String!
        }
    
        type Product implements Node {
          id: ID!
          name: String!
          price: Float!
        }
    
        union SearchResult = User | Product
    
        type Query {
          node(id: ID!): Node
          search(query: String!): [SearchResult!]!
        }
      
    

    V tomto příkladu User i Product implementují rozhraní Node, které definuje společné pole id. Union typ SearchResult představuje výsledek vyhledávání, který může být buď User, nebo Product. Klienti se mohou dotazovat na pole `search` a poté pomocí pole `__typename` určit, jaký typ výsledku obdrželi.

    Výhody:

    Zvažte:

    5. Vzor Connection (pro stránkování)

    Vzor Connection je standardní způsob implementace stránkování v GraphQL API. Poskytuje konzistentní a efektivní způsob, jak načítat velké seznamy dat po částech.

    Jak to funguje:

    Příklad:

      
        type User {
          id: ID!
          name: String!
          email: String!
        }
    
        type UserEdge {
          node: User!
          cursor: String!
        }
    
        type UserConnection {
          edges: [UserEdge!]!
          pageInfo: PageInfo!
        }
    
        type PageInfo {
          hasNextPage: Boolean!
          hasPreviousPage: Boolean!
          startCursor: String
          endCursor: String
        }
    
        type Query {
          users(first: Int, after: String, last: Int, before: String): UserConnection!
        }
      
    

    Výhody:

    Zvažte:

    Globální aspekty

    Při návrhu schématu GraphQL pro globální publikum zvažte tyto další faktory:

    Zvažte například pole pro popis produktu:

    
    type Product {
     id: ID!
     name: String!
     description(language: String = "en"): String!
    }
    
    

    To umožňuje klientům vyžádat si popis v konkrétním jazyce. Pokud není jazyk specifikován, použije se výchozí angličtina (`en`).

    Závěr

    Škálovatelný návrh schématu je nezbytný pro vytváření robustních a udržovatelných GraphQL API, která zvládnou požadavky globální aplikace. Dodržováním principů uvedených v tomto článku a používáním vhodných návrhových vzorů můžete vytvářet API, která jsou snadno pochopitelná, upravitelná a rozšiřitelná a zároveň poskytují vynikající výkon a škálovatelnost. Nezapomeňte své schéma modularizovat, skládat a abstrahovat a zohlednit specifické potřeby vašeho globálního publika.

    Přijetím těchto vzorů můžete odemknout plný potenciál GraphQL a vytvářet API, která budou pohánět vaše aplikace po mnoho let.