Статьи

Исследуйте GraphQL с помощью Apollo & React: создайте базу данных супергероев

Интересуетесь всем шумом, связанным с GraphQL , но не совсем уверены, почему вы должны быть взволнованы? Вы в нужном месте! Мы расскажем о том, что такое GraphQL, и дадим вам возможность получить практический опыт.

Давайте начнем с того, что очистим эфир и ответим на вопрос в 20 000 долларов: что такое GraphQL? Нет, это не скрытая функция на вашем TI-89. В основе лежит язык запросов — или, точнее, спецификация запросов, — который можно использовать для извлечения данных практически из любого источника данных.

Более того, он позволяет вам получать именно те данные, которые вам нужны — ни больше, ни меньше — за один сетевой запрос. Хотя это может показаться не самой сексуальной технологией, появившейся на фабрике инноваций Facebook, вы можете просто приятно удивиться, насколько она может быть полезной.

Все, что нужно, это сервер Apollo, который будет выступать в качестве нашей конечной точки, и приложение React, использующее клиент Apollo для использования любых данных внутри. Сначала мы займемся сервером.

Начало работы с сервером Apollo

Чтобы запустить наш сервер Apollo, создайте папку с именем apollo-server Затем войдите в этот каталог и выполните следующую команду npmустановлены npm и Node , верно? — чтобы получить фреймворк Apollo:

 npm install apollo-server apollo-server-express graphql

Теперь, когда у вас есть различные кусочки сервера Apollo, пришло время рассказать нашему серверу, что обслуживать. Создайте пустой файл index.jsapollo-server

 const { ApolloServer, gql } = require('apollo-server');

Эта строка просто извлекает необходимые объекты для запуска сервера Apollo и парсинга наших строк запроса в документы запроса для GraphQL.

Наша первая схема GraphQL

Далее, давайте добавим нашу первую схему:

 // This will be our GraphQL schema
const typeDefs = gql`
  type User {
    id: ID!
    name: String
    superpowers: [Superpower]!
  }

  type Superpower {
    id: ID!
    text: String
  }

  type Query {
    users: [User]
    user(id: ID!): User
  }
`;

Здесь мы добавляем наши определения типов. Первый имеет тип Useridnamesuperpowers Второй простой idtext Наконец, третий определяет два приемлемых запроса — usersuserid

Довольно легко, правда?

Добавление тире данных

Далее, давайте добавим некоторые фиктивные данные, чтобы оживить нашу схему:

 // This will be our mock data to query
const users = [{
  id: '1',
  name: 'Peter Parker',
  superpowers: [{
    id: '1',
    text: 'Web slinging'
  },{
    id: '2',
    text: 'Spidey sense'
  }]
},{
  id: '2',
  name: 'Tony Stark',
  superpowers: [{
    id: '3',
    text: 'Industrial design'
  },{
    id: '4',
    text: 'Robotic fashion'
  }]
}];

Все, что мы делаем здесь, это добавляем двух пользователей к нашим фиктивным данным. Стоит отметить, что GraphQL не относится только к запросам массивов JavaScript. Это может быть любая база данных или другая конструкция данных. Мы просто сохраняем простоту, чтобы сосредоточиться на задаче.

Не забывайте про резольверы

Далее нам нужно сказать GraphQL, как интерпретировать запросы, которые мы определили выше. Это делается с помощью резольверов:

 // This will be a map of functions to return the data described by our schema
const resolvers = {
  Query: {
    users: () => {
      return users
    },
    user: (root, { id }) => {
      return users.find(user => user.id === id);
    },
  },
};

Вы заметите, что первый запрос users Пользователь второго запроса принимает идентификатор пользователя, который должен быть выбран, и возвращает указанного пользователя.

Собираем все вместе

Чтобы завершить работу нашего сервера Apollo, нам просто нужно создать новый экземпляр и начать прослушивать соединения:

 user

Здесь мы отправляем конструктору const server = new ApolloServer({
typeDefs,
resolvers,
});

server.listen().then(({ url }) => {
console.log(`Apollo server started at ${url}`)
});
Все, что нужно, это запустить сервер, но сначала вот как должен выглядеть ваш ApolloServer

 index.js

const { ApolloServer, gql } = require('apollo-server');

// This will be our GraphQL schema
const typeDefs = gql`
type User {
id: ID!
name: String
superpowers: [Superpower]!
}

type Superpower {
id: ID!
text: String
}

type Query {
users: [User]
user(id: ID!): User
}
`;

// This will be our mock data to query
const users = [{
id: ‘1’,
name: ‘Peter Parker’,
superpowers: [{
id: ‘1’,
text: ‘Web slinging’
},{
id: ‘2’,
text: ‘Spidey sense’
}]
},{
id: ‘2’,
name: ‘Tony Stark’,
superpowers: [{
id: ‘3’,
text: ‘Industrial design’
},{
id: ‘4’,
text: ‘Robotic fashion’
}]
}];

// This will be a map of functions to return the data described by our schema
const resolvers = {
Query: {
users: () => {
return users
},
user: (root, { id }) => {
return users.find(user => user.id === id);
},
},
};

const server = new ApolloServer({
typeDefs,
resolvers,
});

server.listen().then(({ url }) => {
console.log(`Apollo server started at ${url}`)
});
node index.jshttp://localhost:4000/

Вас должна приветствовать игровая площадка GraphQL, которая позволяет вам пробовать интерактивные запросы к созданной вами схеме.

Собираюсь на практике

Давайте проверим это, введя этот запрос в левой панели:

 query {
  user(id: 1) {
    name
  }
}

Здесь мы используем useridname Результат в левой панели — после нажатия кнопки «play-like» — должен выглядеть следующим образом:

 {
  "data": {
    "user": {
      "name": "Peter Parker"
    }
  }
}

Допустим, вы тоже хотите взглянуть на его суперспособности. Все, что вам нужно сделать, это запросить это поле:

 query {
  user(id: 1) {
    name,
    superpowers {
      text
    }
  }
}

Мы добавили поле superpowers Результат теперь должен отображать каждую сверхдержаву для нашего первого пользователя:

 {
  "data": {
    "user": {
      "name": "Peter Parker",
      "superpowers": [
        {
          "text": "Web slinging"
        },
        {
          "text": "Spidey sense"
        }
      ]
    }
  }
}

Скажем, мы хотим захватить всех пользователей и их суперспособности, мы можем положиться на запрос users

 query {
  users {
    id,
    name,
    superpowers {
      text
    }
  }
}

И результат:

 {
  "data": {
    "users": [
      {
        "id": "1",
        "name": "Peter Parker",
        "superpowers": [
          {
            "text": "Web slinging"
          },
          {
            "text": "Spidey sense"
          }
        ]
      },
      {
        "id": "2",
        "name": "Tony Stark",
        "superpowers": [
          {
            "text": "Industrial design"
          },
          {
            "text": "Robotic fashion"
          }
        ]
      }
    ]
  }
}

Забота только о сверхдержавах? Мы можем сделать это тоже:

 query {
  users {
    superpowers {
      text
    }
  }
}

И вы получите:

 {
  "data": {
    "users": [
      {
        "superpowers": [
          {
            "text": "Web slinging"
          },
          {
            "text": "Spidey sense"
          }
        ]
      },
      {
        "superpowers": [
          {
            "text": "Industrial design"
          },
          {
            "text": "Robotic fashion"
          }
        ]
      }
    ]
  }
}

На этом этапе вы сможете оценить высочайшую гибкость и привлекательность GraphQL. С помощью одного запроса и соединения мы можем получить любой фрагмент данных, который нам нужен. Все, что необходимо, — это хорошо разработанная схема и средства разрешения для ее поддержки.

Более того, back-end разработчики и front-end разработчики могут делать свое дело практически независимо. Поскольку схема действует как посредник, обе группы могут эффективно избегать наступления друг другу на ноги. И действительно, это вкратце GraphQL. Прежде чем закончить этот урок, давайте посмотрим, как интегрировать эти запросы в реальное приложение React.

Введение в реакцию на смесь

Вернитесь в корневой рабочий каталог и выполните следующие команды, чтобы настроить загрузочное приложение React с необходимыми библиотеками GraphQL и Apollo:

 npm install -g create-react-app
create-react-app my-graphql
cd my-graphql
npm install apollo-boost react-apollo graphql

Затем замените содержимое src/index.js

index.js:

 import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { HttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'

import App from './App'

const client = new ApolloClient({
    link: new HttpLink({ uri: 'http://localhost:4000/graphql' }),
    cache: new InMemoryCache()
})

ReactDOM.render(
    <ApolloProvider client={client}>
    <App />
    </ApolloProvider>,
    document.getElementById('root')
)

Все, что нам нужно здесь — это обычный импорт приложения React вместе с клиентом Apollo для взаимодействия с нашим новым сервером Apollo. Для создания клиента Apollo нам просто нужна ссылка на сервер http://localhost:4000/graphql При этом мы просто визуализируем приложение.

Далее нам нужно настроить приложение для запроса и отображения данных, представленных нашим сервером Apollo. Идем дальше и заменим src/App.js

App.js:

 import React from 'react'
import { Query } from 'react-apollo'
import { gql } from 'apollo-boost'

const TEST_QUERY = gql`
  {
    user(id: 1) {
      id,
      name,
      superpowers {
        text
      }

  }}
`;

const App = () => (
  <Query query={TEST_QUERY}>
  {({ data: { user }, loading }) => {
      if (loading || !user) {
        return <div>Loading ...</div>;
      }
      return (
    <p>
        {user.name} ({user.id}) has the following superpowers:
        <ul>
        {user.superpowers.map(superpower => (
            <li>
                {superpower.text}
            </li>
        ))}
        </ul>
    </p>
      );
    }}
  </Query>
);

export default App

Вы должны увидеть некоторые знакомые шаблоны здесь. Сначала мы используем gql Затем мы передаем документ на наш сервер с тегом Query Именно здесь мы можем отформатировать результаты в симпатичном приложении React.

Запустите сервер с помощью npm starthttp://localhost:3000/

И на этом наш урок завершен. Вы создали сервер Apollo и передали ему несколько простых структур данных. Вы узнали, как писать схемы и средства распознавания для определения взаимодействий с данными. Затем вы практиковались в запросе определенных фрагментов этих данных. Наконец, вы связали все это вместе с приложением React, которое извлекает данные с сервера и представляет их в хорошо отформатированном виде.

Хотя этого должно быть достаточно для начала работы с интеграцией GraphQL в ваши будущие проекты, многое еще предстоит узнать. Мутации для добавления и изменения данных — отличный следующий шаг.

Надеюсь, вам понравился этот урок — счастливого программирования!