Apollo GraphQL: Как да създадем приложение с пълен стек с React и Node Js

Apollo Client е пълна библиотека за управление на състоянието за приложения на JavaScript. Това е мощен инструмент, тъй като може да се използва както отзад, така и отпред.

В този урок ще го използваме отпред и отзад, като изградим Apollo GraphQL сървър с Node JS. След това ще консумираме данните от страна на клиента, използвайки React JS.

Ако не сте запознати с GraphQl, този урок може да ви помогне. В противен случай да започнем.

  • Изграждане на сървъра с Apollo, Node и GraphQl
  • Схема GraphQl
  • Резолютори на GraphQl
  • Създаване на Apollo Server
  • Изграждане на клиентска страна с React
  • Свързване на React с Apollo
  • Извличане на данните
  • Показване на данните

Изграждане на сървъра с Apollo, Node и GraphQl

В това ръководство ще използвам Github API, за да разполагам с данни за показване и тази операция ще се извършва от GraphQl сървъра, изграден с Apollo и Node JS.

За да се случи това, трябва да изпълним следната команда на терминала, за да настроим нов проект на Node JS:

 yarn init 

След като настройката приключи, вече можем да инсталираме необходимите пакети, като изпълним тази команда:

 yarn add apollo-server graphql axios 

Чудесно, сега имаме всичко, което ни е необходимо за изграждане на сървър. Така че първо нека създадем нов файл app.jsв корена, който ще бъде входната точка на нашия сървър.

След това трябва да дефинираме схема на Graphql, която отразява начина, по който трябва да изглеждат данните ни.

Схема GraphQl

Схема описва формата на вашата графика с данни. Той дефинира набор от типове с полета, които се попълват от задните ви хранилища за данни. И така, нека добавим нова схема във app.jsфайла.

  • app.js
const { ApolloServer, gql } = require("apollo-server") const axios = require("axios") const typeDefs = gql` type User { id: ID login: String avatar_url: String } type Query { users: [User] } ` 

Както можете да видите, ние не използваме всички данни, предоставени от API на Github. Нуждаем се само от идентификатора, който ще се използва като референтен ключ в React App, данните за вход и avatar_url. Имаме и заявка, usersкоято връща масив от потребители.

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

Резолютори на GraphQl

Резолюторът е колекция от функции, която помага да се генерира отговор от GraphQL заявка. И така, нека добавим нов преобразувател във app.jsфайла.

  • app.js
const resolvers = { Query: { users: async () => { try { const users = await axios.get("//api.github.com/users") return users.data.map(({ id, login, avatar_url }) => ({ id, login, avatar_url, })) } catch (error) { throw error } }, }, } 

Резолюторът трябва да съответства на съответната схема по име. Следователно тук се usersотнася до usersзаявката, дефинирана в нашата схема. Това е функция, която извлича данните от приложния програмен интерфейс (API) с помощта axiosи връща според очакванията идентификационния номер, данните за вход и avatar_url.

И тази операция може да отнеме време, за да завърши. Ето защо async / await се използва тук, за да се справи с него.

С това вече можем да създадем Apollo Server в следващия раздел.

Създаване на Apollo Server

Ако си спомняте, във app.jsфайла бяхме импортирали ApolloServerот apollo-serverпакета. Това е конструктор, който получава обект като аргумент. И този обект трябва да съдържа схемата и преобразувателя, за да може да създаде сървъра.

Така че, нека да променим app.jsмалко с ApolloServer.

  • app.js
const server = new ApolloServer({ typeDefs, resolvers, }) // typeDefs: typeDefs, // resolvers: resolvers server.listen().then(({ url }) => console.log(`Server ready at ${url}`)) 

Тук предаваме като параметър обект, който държи схемата и преобразувателя, за ApolloServerда създаде сървъра и след това го слуша. С това на място вече имаме функционален сървър, с който да работим.

Вече можете да играете с него и да изпращате заявки с помощта на GraphQL playground, като изпълните тази команда:

 yarn start 

Вече можете да го визуализирате на //localhost:400

  • Пълният app.jsфайл
const { ApolloServer, gql } = require("apollo-server") const axios = require("axios") const typeDefs = gql` type User { id: ID login: String avatar_url: String } type Query { users: [User] } ` const resolvers = { Query: { users: async () => { try { const users = await axios.get("//api.github.com/users") return users.data.map(({ id, login, avatar_url }) => ({ id, login, avatar_url, })) } catch (error) { throw error } }, }, } const server = new ApolloServer({ typeDefs, resolvers, }) server.listen().then(({ url }) => console.log(`Server ready at ${url}`)) 

Сървърът сам по себе си не прави много. Трябва да добавим начален скрипт във package.jsonфайла, за да, както се досещате, стартирате сървъра.

  • package.json
 // first add nodemon: yarn add nodemon --dev "scripts": { "start": "nodemon src/index.js" } 

С това имаме сървър за извличане на данни от API на Github. Така че сега е време да преминете към страната на клиента и да консумирате данните.

Хайде да го направим.

yaay

Изграждане на клиентска страна с React

Първото нещо, което трябва да направим, е да създадем ново приложение React, като изпълним следната команда в терминала:

npx create-react-app client-react-apollo 

След това трябва да инсталираме пакетите Apollo и GraphQl:

 yarn add apollo-boost @apollo/react-hooks graphql 

Сега можем да свържем Apollo с нашето приложение React, като актуализираме index.jsфайла.

Свързване на React с Apollo

  • index.js
import React from 'react'; import ReactDOM from 'react-dom'; import ApolloClient from 'apollo-boost' import { ApolloProvider } from '@apollo/react-hooks'; import App from './App'; import './index.css'; import * as serviceWorker from './serviceWorker'; const client = new ApolloClient({ uri: '//7sgx4.sse.codesandbox.io' }) ReactDOM.render(     , document.getElementById('root') ); serviceWorker.unregister(); 

As you can see, we start by importing ApolloClient and ApolloProvider. The first helps us inform Apollo about which URL to use when fetching data. And if no uri is passed to ApolloClient, it will take the current domain name plus /graphql.

The second is the Provider which expects to receive the client object to be able to connect Apollo to React.

That said, we can now create a component that shows the data.

Fetching the data

  • App.js
import React from "react" import { useQuery } from "@apollo/react-hooks" import gql from "graphql-tag" import "./App.css" const GET_USERS = gql` { users { id login avatar_url } } ` 

Here, we have a simple GraphQL query that fetches the data. That query will be passed later to useQuery to tell Apollo which data to fetch.

  • App.js
const User = ({ user: { login, avatar_url } }) => ( 

{login}

See profile )

This presentational component will be used to display a user. It receives the data from the App component and displays it.

Showing the data

  • App.js
function App() { const { loading, error, data } = useQuery(GET_USERS) if (error) return 

Something went wrong!

if (loading) return

Loading...

return (

Github | Users

{data.users.map(user => ( ))} ) } export default App

The useQuery hook provided by Apollo receives the GraphQL query and returns three states: the loading, the error, and the data.

If the data are successfully fetched, we pass it to the User component. Otherwise we throw an error.

  • The complete App.js file
import React from "react" import { useQuery } from "@apollo/react-hooks" import gql from "graphql-tag" import "./App.css" const GET_USERS = gql` { users { id login avatar_url } } ` const User = ({ user: { login, avatar_url } }) => ( 

{login}

See profile ) function App() { const { loading, error, data } = useQuery(GET_USERS) if (error) return

Something went wrong!

if (loading) return

Loading...

return (

Github | Users

{data.users.map(user => ( ))} ) } export default App

Great! With that, we are now done building a full-stack Apollo GraphQL app using React and Node JS.

Preview the Apollo GraphQL Server here

Preview the React App here

Find the source code here

You can find other great content like this on my blog

Thanks for reading!

congrats