Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst...
Transcript of Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst...
![Page 1: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/1.jpg)
Удобные API сGraphQL
![Page 2: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/2.jpg)
Михаил Новиковtwitter.com/freiksenet
CTO @ Reindex
![Page 3: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/3.jpg)
Современныеприложения
![Page 4: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/4.jpg)
![Page 5: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/5.jpg)
![Page 6: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/6.jpg)
{ id: "1", url: "some-url.jpg", createdAt: "2016-05-26T18:00:00", likes: 755, author: { id: "2", username: "mikkelerbeer", displayName: "Mikkeler", }, comments: [ { id: "3", content: "LIU XIAODONG", createdAt: "2016-05-26T18:05:00", author: { username: "mikkelerbeer", displayName: "Mikkeler", }, }, ],}
![Page 7: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/7.jpg)
id: "1",url: "some-url.jpg",createdAt: "2016-05-26T18:00:00",likes: 755,
author: { id: "2", username: "mikkelerbeer", displayName: "Mikkeler",},
{ id: "3", content: "LIU XIAODONG", createdAt: "2016-05-26T18:05:00", author: { username: "mikkelerbeer", displayName: "Mikkeler", },},
![Page 8: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/8.jpg)
Хороший бакендОтдает данные быстро
Удобен для разработчика
![Page 9: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/9.jpg)
REST
![Page 10: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/10.jpg)
Каноничный RESTОдин ресурс - один тип данныхid или url связанных обьектов
![Page 11: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/11.jpg)
Каноничный RESTconst picture = await fetch('/picture/1');picture.author = await fetch(`/author/${picture.author}`);picture.comments = await fetch('/picture/1/comments');picture.comments = await Promise.all( picture.comments.map((comment) => ({ ...comment, author: await fetch(`/author/${comment.author}`) })));
![Page 12: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/12.jpg)
Каноничный RESTОчень много запросовАбсолютно не практичен
![Page 13: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/13.jpg)
Вложенный RESTОтдаем данные которые нужны
Толстые ресурсыМного ресурсов
![Page 14: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/14.jpg)
Вложенный RESTЗаточен под вьюшкуПроблемы с reuse
![Page 15: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/15.jpg)
Настраиваемый RESTconst picture = await fetch( '/picture/1?include=author,comments,comments.author');
![Page 16: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/16.jpg)
НастраиваемыйREST
Много работыМожет превратится в легаси
![Page 17: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/17.jpg)
REST этофилософия
![Page 18: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/18.jpg)
REST не идеалендля приложений
![Page 19: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/19.jpg)
Что естьидеальныйбакенд?
Выбор нужных данныхПросто имплементировать
Отдает метаданные
![Page 20: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/20.jpg)
GraphQL
![Page 21: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/21.jpg)
GraphQL - языкзапросов
![Page 22: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/22.jpg)
{ id: "1", url: "some-url.jpg", createdAt: "2016-05-26T18:00:00", likes: 755, author: { id: "2", username: "mikkelerbeer", displayName: "Mikkeler", }, comments: [ { id: "3", content: "LIU XIAODONG", createdAt: "2016-05-26T18:05:00", author: { id: "2", username: "mikkelerbeer", displayName: "Mikkeler", }, }, ],}
![Page 23: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/23.jpg)
{ pictureById(id: "1") { id url createdAt likes author { id username displayName }, comments { id content createdAt author { username displayName } } }}
![Page 24: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/24.jpg)
GraphQL - сервер
![Page 25: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/25.jpg)
Связанные типы с полями
![Page 26: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/26.jpg)
type User { id: ID! username: String displayName: String pictures: [Picture] comments: [Comment]}
type Picture { id: ID! url: String! author: User! comments: [Comment]}
type Comment { id: ID! author: User! picture: Picture! content: String!}
![Page 27: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/27.jpg)
Поля могут принимать аргументы
![Page 28: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/28.jpg)
{ authorById(id: "1") { id avatar(size: MEDIUM) { url } pictures(limit: 10) { id url } }}
![Page 29: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/29.jpg)
GraphQL -метаданные
![Page 30: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/30.jpg)
GraphQL -идеальный бакенддля продуктов
![Page 31: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/31.jpg)
Relay
![Page 32: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/32.jpg)
Компоненты вместе и с ихданными
![Page 33: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/33.jpg)
![Page 34: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/34.jpg)
const CommentContainer = Relay.createContainer(Comment, { fragments: { comment: () => Relay.QL` fragment on Comment { id text createdAt author { username displayName } } `, },});
![Page 35: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/35.jpg)
const PictureContainer = Relay.createContainer(Comment, { fragments: { picture: () => Relay.QL` fragment on Picture { id url createdAt likes author { ${AuthorPanel.getFragment('user')} } comments { ${Comment.getFragment('comment')} } } `, },});
![Page 36: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/36.jpg)
RelayМеньше бойлерплейта
Клиентский кешPagination
Оптимистичные мутации
![Page 37: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/37.jpg)
GraphQLэкосистема
GraphiQLApollo
HorizonReindex ;)
![Page 38: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/38.jpg)
Как писать GraphQLбакенды
![Page 39: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/39.jpg)
graphql-js
![Page 40: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/40.jpg)
Типизированная схема
![Page 41: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/41.jpg)
const Picture = new GraphQLObjectType({ name: 'Picture', fields: () => ({ id: { type: new GraphQLNonNull(GraphQLID), }, url: { type: GraphQLString, }, author: { type: User, }, comments: { type: new GraphQLList(Picture), }, }),});
![Page 42: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/42.jpg)
const Query = new GraphQLObjectType({ name: 'Query', fields: () => ({ pictureById: { type: Picture, }, }),});
![Page 43: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/43.jpg)
Данные подключаются черезresolve методы
![Page 44: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/44.jpg)
const Query = new GraphQLObjectType({ name: 'Query', fields: () => ({ pictureById: { type: Picture, resolve() { id: "1", url: "some-url.jpg", author: { ... }, comments: [ ... ], } }, }),});
![Page 45: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/45.jpg)
resolve берет любой Promise
![Page 46: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/46.jpg)
const Query = new GraphQLObjectType({ name: 'Query', fields: () => ({ pictureById: { type: Picture, resolve(parent, { id }) { return db.collection('Picture').find({ _id: id }); } }, }),});
![Page 47: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/47.jpg)
resolve можно подключить клюбому полю
![Page 48: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/48.jpg)
const Picture = new GraphQLObjectType({ name: 'Picture', fields: () => ({ ..., author: { type: User, resolve(parent) { return db.collection('User').find({ _id: parent.author }); } }, }),});
![Page 49: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/49.jpg)
GraphQL как APIgateway
![Page 50: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/50.jpg)
const Picture = new GraphQLObjectType({ name: 'Picture', fields: () => ({ ..., comments: { type: new GraphQLList(Picture), resolve(parent) { return fetch( `/third-party/comments/${parent.commentId}` ); }, }, }),});
![Page 51: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/51.jpg)
Производительность
![Page 52: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/52.jpg)
{ pictureById(id: "1") { id url createdAt likes author { id username displayName }, comments { id content createdAt author { username displayName } } }}
![Page 53: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/53.jpg)
ПроизводительностьN+1 problemБэтчинг
Анализ запросов
![Page 54: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/54.jpg)
Будущее GraphQL
![Page 55: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/55.jpg)
НедостаткиGraphQL
![Page 56: Удобные API с GraphQLpublic.jugru.org/holyjs/2016/spb/day_1/track_2/novikov.pdfconst PictureContainer = Relay.createContainer(Comment, {fragments: {picture: => Relay.QL` fragment](https://reader034.fdocuments.us/reader034/viewer/2022042300/5eca7b7c03de2c4cd02dc2e9/html5/thumbnails/56.jpg)
Use GraphQL ;)