Джумак Евгений
React
Redux
Redux-Saga
👍 Фронтенд умеет работать с REST
Бекенд умеет работать с REST
Фреймворки умеют работать с REST
Много удобных инструментов
Есть устоявшиеся согласованности
React
Redux
Redux-Saga
GraphQL
GET /items/{id}
GET /item/{id}
GET /items
GET /items/all
или
или
POST /items/{id}
PUT /items/{id}
или
200 или 201
400 или 405
500 или 501
GET /rewards/{id}
GET /user/{id}/rewards/{id}
{
"id": 17652313,
"title": "My 100th achievement",
"xp": 500,
"date": "2017-05-13 07:59:38"
...
}{
"id": "17652313",
"title": null,
"xp": "500",
...
}Он ждет пока бекендер
добавит новое поле
type Reward {
id: ID!
title: String!
xp: Int!
date: DateTime!
}Describe your schema
{
reward(id: "113") {
title
date
}
}Ask for what you want
{
"title": "My 100th achievement",
"date": "2017-05-13 07:59:38"
}Get predictable results
const query = `
user(id: "200450") {
email
}
`;
await fetch("https://example.com/graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query })
});
Неудобно
Нефункционально
Нет кэширования
Фреймворки
React, React-Native
Framework agnostic
Гибкость
Нужна своя схема
Любая схема
Сложность
Сложно
Терпимо
DX
Отлично
Много ручной работы
SSR
Нет*
Да
Документация
Терпимо
Отлично
Вес
31.2 kb
36.2 kb
npm install apollo-boost react-apollo graphql
Все необходимое для настройки Apollo Client
Парсер схемы
Интеграция с уровнем представления React
import ApolloClient, { ApolloProvider } from "apollo-boost";
const client = new ApolloClient({
uri: "https://48p1r2roz4.sse.codesandbox.io"
});
const App = () => (
<ApolloProvider client={client}>
<MyApp />
</ApolloProvider>
);{
allFilms(
first: 5
after: "YXJyYXljb25uZWN0aW9uOjQ="
) {
edges {
node {
title
}
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}
{
allFilms(first: 5, skip: 5) {
title
}
}
<button
onClick={() =>
fetchMore({
variables: {
after: data.allFilms.pageInfo.endCursor
},
updateQuery: (prev, { fetchMoreResult }) => ({
allFilms: {
...fetchMoreResult.allFilms,
edges: [
...prev.allFilms.edges,
...fetchMoreResult.allFilms.edges
]
}
})
})
}
>
Load more
</button>type User {
id
name
}import { InMemoryCache, defaultDataIdFromObject } from "apollo-cache-inmemory";
const cache = new InMemoryCache({
dataIdFromObject: object => {
switch (object.__typename) {
case "foo":
// use `key` as the primary key
return object.key;
case "bar":
// use `bar` prefix and `blah` as the primary key
return `bar:${object.blah}`;
default:
// fall back to default handling
return defaultDataIdFromObject(object);
}
}
});
{
post(id: '5') {
id
score
}
}mutation {
upvotePost(id: '5') {
id
score
}
}"Post:5"
{
id: 1
score: 6.4
}"Post:5"
{
id: 1
score: 7.8
}const { todo } = client.readQuery({
query: gql`
query ReadTodo {
todo(id: 5) {
text
}
}
`,
});const todo = client.readFragment({
// returned by `dataIdFromObject`
id: ...,
fragment: gql`
fragment myTodo on Todo {
text
}
`,
});readQuery()
readFragment()
mutate({
//... insert comment mutation
refetchQueries: ['comments'],
})const DontReadTheComments = ({ repoFullName }) => (
<Subscription
subscription={COMMENTS_SUBSCRIPTION}
variables={{ repoFullName }}
>
{({ data: { commentAdded }, loading }) => (
<h4>New comment: {!loading && commentAdded.content}</h4>
)}
</Subscription>
);
<Query query={GET_USER_WITH_ID} ssr={false}>
{({ data }) => <span>I won't be run on the server</span>}
</Query>Batched операции по скорости всегда равны самому медленному запросу
npm install -g apollo-codegen
apollo-codegen introspect-schema http://localhost:8080/graphql \
--output schema.json
# TypeScript
apollo-codegen generate **/*.graphql \
--schema schema.json --target typescript \
--output operation-result-types.ts
# Flow
apollo-codegen generate **/*.graphql \
--schema schema.json --target flow \
--output operation-result-types.flow.js
# Scala
apollo-codegen generate **/*.graphql \
--schema schema.json --target scala \
--output operation-result-types.scala👉 Вам приходится ждать изменений от бекенда
У вас сложные, многоуровневые запросы
Вы испытываете проблемы с REST
Вам нужны удобные инструменты работы со схемой
Вы хотите интроспекции в IDE