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

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

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

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

C27317d1ebe4e4a01504acab9d87fe61?s=128

Polina Gurtovaya

August 02, 2019
Tweet

Transcript

  1. GraphQL для разработки и общения Полина Гуртовая Evil Martians

  2. None
  3. None
  4. None
  5. О чём это мы?

  6. React Redux ~10 SPA eBaymag

  7. Проблема

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

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

    "DE" } } } Проблема 1: Беспорядок в данных
  10. { "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
  11. // 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: Недостаточно знаний о данных
  12. GraphQL все исправит!

  13. Что такое GraphQL?

  14. “GraphQL is unapologetically driven by the requirements of views and

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

    whatever they like mutation { make_me_a _coffee } GraphQL это магия? ❌
  16. Матчасть

  17. Как это работает GQL service Client Document Как это работает

  18. Консолька

  19. Консолька

  20. Operations • Query • Mutation • Subscription

  21. Как это работает GQL service Client Document Query Mutation Subscription

    Schema Response Data Errors Как это работает
  22. 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
  23. 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 }
  24. 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 }
  25. 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]
  26. Как это работает GQL service Client Document Query Mutation Subscription

    Schema Execute Validate Response Data Errors
  27. 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
  28. Хочу все знать! (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" }, …
  29. Реальность

  30. Фронт теперь откровенной фигни не пришлёт 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" ] } ] }
  31. Схема => Доки

  32. Схема + Типы => •Подсветка + Автодополнение •Codegen

  33. Хуки на страже надежности

  34. Избавляемся от лишних сущностей Интерфейс Может как-то так? Showcase Site

  35. Отдельный слой логики для интерфейса { site { code name

    active } } Props! <Site {...site} />
  36. Инструменты

  37. Большие и страшные Apollo Relay Маленькие и дружелюбные graphql-request graphql-tag

    graphql-js
  38. Как работают GraphQL фреймворки? query GetUsers { viewer { name

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

    Normalized Cache <UserInfo name={props.name}/>
  40. query GetUserAgain {…} Normalized Cache <UserInfo name={props.name}/> { user: {

    name: "Winnie" } }
  41. Проблемы ^^

  42. N + 1 query { products(limit: 10) { name user

    { email } } }
  43. Бесконечные запросы type User { products: [Product] } type Product

    { user: User } query { user { products { user { products { user { products { user { ... } } } } } } } }
  44. С кешированием все хитро

  45. Что выбрать? Сложные фреймворки слишком сложные. Простые библиотеки слишком простые

    :(
  46. Что дальше ?

  47. Доки + спецификация graphql.org (docs + spec)

  48. evl.ms/blog

  49. Спасибо ! @polina_gurtovaya