Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GraphQL для разработки и общения

GraphQL для разработки и общения

История о том, как один из наших проектов переехал на GraphQL.
Переезд оказался успешным и поучительным. Мы пытались решить стандартные проблемы: беспорядок и непонятность данных, overfetching. В результате мы получили намного больше чем ожидали.
Во-первых мы решили наши изначальные проблемы.
Во-вторых, мы упростили наше общение с бекендом => ускорили разработку
В-третьих, мы получили веселую генерацию кода и возможность изобретать велосипеды :)

Polina Gurtovaya

August 02, 2019
Tweet

More Decks by Polina Gurtovaya

Other Decks in Programming

Transcript

  1. { "showcase": { "name": “ebay.de", "totalItems": 253, "siteCode": “DE" }

    } Проблема 1: Беспорядок в данных
  2. { "showcase": { "name": “ebay.de", "active": true, "site": { "code":

    "DE" } } } Проблема 1: Беспорядок в данных
  3. { "showcase": { "name": "ebay.com", "active": true, "id": "92", "primary":

    true, "currency": "USD", "site": { "code": "US", "name": "ebay.com", "currency": "USD", "country": "US", "domain": "ebay.com" } } } <Site name={site.name} code={site.code} /> Проблема 2: Overfetching
  4. // lodash get(obj, "showcase.site.code"); // ramda path(["showcase", "site", "code"], obj);

    <Flag code={showcase.site.code} /> { "showcase": { "name": “ebay.au", "active": true, "site": { "code": “AU” } } Проблема 3: Недостаточно знаний о данных
  5. “GraphQL is unapologetically driven by the requirements of views and

    the front-end engineers that write them Из спеки: Frontend Backend GraphQL для фронтов? ✓
  6. “GraphQL is DB over http and your clients can do

    whatever they like mutation { make_me_a _coffee } GraphQL это магия? ❌
  7. Как это работает GQL service Client Document Query Mutation Subscription

    Schema Response Data Errors Как это работает
  8. query { viewer { id name } product(id: 5) {

    title quantity tags } } field Selection set Language type Query { viewer: User product(id: ID!): Product … } Schema type Product { title: String quantity: Float! tags: [String] user: User … } Input type Output type Object type Scalar type Wrapper type
  9. Unions { info { id ... on User { name

    } ... on Product { title } } } union UserOrProduct = User | Product type Query { info: UserOrProduct } type User { id: ID! name: String } type Product { id: ID! title: String }
  10. Interfaces { info { id ... on User { name

    } ... on Product { title } } } interface Node = { id: ID! } type Product implements Node { id: ID! title: String } type User implements Node { id: ID! name: String } type Query { info: Node }
  11. Fragments query { viewer { email name id } product(id:

    5) { title quantity users { email name id } } } fragment UserInfo on User { email name id } query { viewer { ...UserInfo } product(id: 5) { title quantity users { ...UserInfo } } } viewer: User users: [User]
  12. Execution query { product(id: 5) { title user { name

    id } } } Рекурсивно обходим наш граф и выполняем каждое поле { Query: { product: (_, { id }) => ({ id, title: `Product${id}`, user: { id: 1 } }) }, User: { name: ({ id }) => `User${id}` } } User
  13. Хочу все знать! (Introspection) { __schema { directives { name

    } } __type(name: "Query"){ fields { name description } } } { "data": { "__schema": { "directives": [ … { "name": "deprecated" } ] }, "__type": { "fields": [ { "name": "address", "description": "Get seller's address by ID" }, …
  14. Фронт теперь откровенной фигни не пришлёт mutation { make_me_a_coffee }

    { "errors": [ { "message": "Field ‘make_me_a_coffee' doesn't exist on type 'Mutation'", "locations": [ { "line": 2, "column": 3 } ], "fields": [ "mutation", "make_me_a_coffee" ] } ] }
  15. Как работают GraphQL фреймворки? query GetUsers { viewer { name

    id } } <Query query={GetUsers}> ... <UserInfo name={props.name}/> </Query> import { Query } from
  16. query GetUser {…} { user: { name: "Winnie" } }

    Normalized Cache <UserInfo name={props.name}/>
  17. Бесконечные запросы type User { products: [Product] } type Product

    { user: User } query { user { products { user { products { user { products { user { ... } } } } } } } }