Giới thiệu đầy đủ về Apollo, bộ công cụ GraphQL

Apollo là một bộ công cụ để tạo máy chủ GraphQL và sử dụng API GraphQL. Hãy cùng Apollo khám phá chi tiết cả Apollo Client và Apollo Server.

The Apollo Logo

Giới thiệu về Apollo

Trong vài năm gần đâyGraphQLcực kỳ phổ biến như một cách tiếp cận thay thế để xây dựng API qua REST.

GraphQL là một cách tuyệt vời để cho phép khách hàng quyết định dữ liệu nào họ muốn được truyền qua mạng, thay vì yêu cầu máy chủ gửi một tập dữ liệu cố định.

Ngoài ra, nó cho phép bạn chỉ định các tài nguyên lồng nhau, giảm rất nhiều việc qua lại đôi khi được yêu cầu khi xử lý các API REST.

Apollo là một nhóm và cộng đồng xây dựng dựa trên GraphQL và cung cấp các công cụ khác nhau giúp bạn xây dựng các dự án của mình.

Các công cụ do Apollo cung cấp chủ yếu là 3:Khách hàng,Người phục vụ,Động cơ.

Khách hàng Apollogiúp bạn sử dụng API GraphQL, với sự hỗ trợ cho các công nghệ web giao diện người dùng phổ biến nhất bao gồm React,Vue, Angular, Ember, Meteor, v.v. và phát triển bản địa trên iOS và Android.

Máy chủ Apollolà phần máy chủ của GraphQL, giao diện với phần phụ trợ của bạn và gửi phản hồi trở lại các yêu cầu của khách hàng.

Động cơ Apollolà cơ sở hạ tầng được lưu trữ (SAAS) đóng vai trò là người trung gian giữa máy khách và máy chủ của bạn, cung cấp bộ nhớ đệm, báo cáo hiệu suất, đo tải, theo dõi lỗi, thống kê sử dụng trường lược đồ, thống kê lịch sử và nhiều tính năng khác. Nó hiện miễn phí tới 1 triệu yêu cầu mỗi tháng và là phần duy nhất của Apollo không phải là nguồn mở và miễn phí, đồng thời cung cấp tài trợ cho phần nguồn mở của dự án.

Cần lưu ý rằng 3 công cụ đó không được liên kết với nhau theo bất kỳ cách nào và bạn có thể chỉ sử dụng Apollo Client để giao tiếp với API của bên thứ 3 hoặc cung cấp API bằng Apollo Server mà không cần phải có client.

Đó là tất cảtương thích với thông số kỹ thuật tiêu chuẩn GraphQL, vì vậy không có công nghệ độc quyền hoặc không tương thích trong Apollo.

Nhưng rất tiện lợi khi có tất cả các công cụ đó cùng một mái nhà, một bộ hoàn chỉnh cho tất cả các nhu cầu liên quan đến GraphQL của bạn.

Apollo cố gắng trở nên dễ sử dụng và dễ đóng góp.

Apollo tập trung vàogiữ mọi thứ đơn giản. Đây là điều quan trọng đối với sự thành công của một công nghệ muốn trở nên phổ biến, vì một số công nghệ hoặc khuôn khổ hoặc thư viện có thể quá mức cần thiết đối với 99% các công ty vừa hoặc nhỏ ở đó và chỉ phù hợp với các công ty lớn có nhu cầu rất phức tạp.

Khách hàng Apollo

Khách hàng Apollolà ứng dụng JavaScript hàng đầu cho GraphQL. Hướng đến cộng đồng, nó được thiết kế để cho phép bạn xây dựng các thành phần giao diện người dùng giao diện với dữ liệu GraphQL, trong việc hiển thị dữ liệu hoặc thực hiện các đột biến khi một số hành động nhất định xảy ra.

Bạn không cần phải thay đổi mọi thứ trong ứng dụng của mình để sử dụng Apollo Client. Bạn có thể bắt đầu chỉ với một lớp nhỏ, một yêu cầu và mở rộng từ đó.

Hơn hết, Apollo Client được xây dựng để trở nên đơn giản, nhỏ gọn và linh hoạt ngay từ đầu.

Trong bài đăng này, tôi sẽ trình bày chi tiết quá trình sử dụng Apollo Client trong một ứng dụng React.

Tôi sẽ sử dụngAPI GitHub GraphQLnhư một máy chủ.

Khởi động ứng dụng React

tôi sử dụngcreate-react-appđể thiết lập ứng dụng React, rất tiện lợi và chỉ bổ sung những thứ chúng ta cần:

npx create-react-app myapp

npxlà lệnh mới nhất có sẵnnpmcác phiên bản. Cập nhật npm nếu bạn không có lệnh này.

và khởi động máy chủ cục bộ của ứng dụng với npm:

npm start

Điều này sẽ kích hoạt một ứng dụng trênlocalhost:3000.

Bây giờ mởsrc/index.js:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById(‘root’)) registerServiceWorker()

và xóa tất cả nội dung này.

Bắt đầu với Apollo Boost

Apollo Boost là cách dễ dàng nhất để bắt đầu sử dụng Apollo Client trong một dự án mới. Chúng tôi sẽ cài đặt nó ngoàireact-apollographql.

Trong bảng điều khiển, chạy

npm install apollo-boost react-apollo graphql

Tạo một đối tượng ApolloClient

Bạn bắt đầu bằng cách nhập ApolloClient từapollo-clienttrongindex.js:

import { ApolloClient } from 'apollo-client'

const client = new ApolloClient()

Theo mặc định, Apollo Client sử dụng/graphqlđiểm cuối trên máy chủ hiện tại, vì vậy hãy sử dụngLiên kết Apollođể chỉ định chi tiết của kết nối đến máy chủ GraphQL bằng cách đặt URI điểm cuối GraphQL.

Một Liên kết Apollo được đại diện bởi mộtHttpLinkđối tượng mà chúng tôi nhập từapollo-link-http.

Apollo Link cung cấp cho chúng tôi một cách để mô tả cách chúng tôi muốn nhận được kết quả của hoạt động GraphQL và những gì chúng tôi muốn làm với phản hồi.

Nói tóm lại, bạn tạo nhiều phiên bản Apollo Link, tất cả đều hoạt động theo yêu cầu GraphQL lần lượt, cung cấp kết quả cuối cùng mà bạn muốn. Một số Liên kết có thể cung cấp cho bạn tùy chọn thử lại một yêu cầu nếu không thành công, theo đợt và nhiều hơn thế nữa.

Chúng tôi sẽ thêm một Liên kết Apollo vào phiên bản Ứng dụng khách Apollo của chúng tôi để sử dụng URI điểm cuối GitHub GraphQLhttps://api.github.com/graphql

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }) })

Bộ nhớ đệm

Chúng tôi vẫn chưa hoàn thành. Trước khi có một ví dụ làm việc, chúng ta cũng phải nóiApolloClientcái nàochiến lược bộ nhớ đệmsử dụng:InMemoryCachelà mặc định và đây là cách tốt để bắt đầu.

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

Sử dụngApolloProvider

Bây giờ chúng ta cần kết nối Apollo Client với cây thành phần của chúng ta. Chúng tôi làm như vậy bằng cách sử dụngApolloProvider, bằng cách gói thành phần ứng dụng của chúng tôi trong tệp React chính:

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

import App from ‘./App’

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

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

Điều này là đủ để hiển thị mặc địnhcreate-react-appmàn hình, với Apollo Client được khởi tạo:

create-react-app running Apollo Client

Cácgqlthẻ mẫu

Bây giờ chúng tôi đã sẵn sàng làm điều gì đó với Apollo Client và chúng tôi sẽ tìm nạp một số dữ liệu từ API GitHub và kết xuất nó.

Để làm như vậy, chúng ta cần nhậpgqlthẻ mẫu ở đầuindex.js:

import gql from 'graphql-tag'

bất kỳ truy vấn GraphQL nào sẽ được tạo bằng thẻ mẫu này, như sau:

const query = gql`
  query {
    ...
  }
`

Thực hiện một yêu cầu GraphQL

Nhập khẩugqllà mục cuối cùng chúng tôi cần trong bộ công cụ của mình.

Bây giờ chúng tôi đã sẵn sàng làm điều gì đó với Apollo Client và chúng tôi sẽ tìm nạp một số dữ liệu từ API GitHub và kết xuất nó.

Nhận mã thông báo truy cập cho API

Điều đầu tiên cần làm làlấy mã thông báo truy cập cá nhântừ GitHub.

GitHub giúp bạn dễ dàng hơn bằng cách cung cấp một giao diện mà từ đó bạn chọn bất kỳ quyền nào bạn có thể cần:

GitHub interface to create a new personal access token

Vì lợi ích của hướng dẫn ví dụ này, bạn không cần bất kỳ quyền nào trong số những quyền đó, chúng dành cho quyền truy cập vào dữ liệu người dùng riêng tư nhưng chúng tôi sẽ chỉ truy vấn dữ liệu kho lưu trữ công khai.

Tuy nhiên, bạn vẫn cần một mã thông báo.

Mã thông báo bạn nhận được là mộtMã thông báo mang OAuth 2.0.

Bạn có thể dễ dàng kiểm tra nó bằng cách chạy từ dòng lệnh:

$ curl -H "Authorization: bearer ***_YOUR_TOKEN_HERE_***" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

(thay thế***_YOUR_TOKEN_HERE_***với mã thông báo thực tế)

cái nào sẽ cho bạn kết quả

{"data":{"viewer":{"login":"***_YOUR_LOGIN_NAME_***"}}}

hoặc là

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v4"
}

nếu có sự cố, chẳng hạn như nếu bạn quên chèn mã thông báo.

Bây giờ chúng ta cần gửiỦy quyềncùng với yêu cầu GraphQL của chúng tôi, giống như chúng tôi đã làm trongcurlyêu cầu trên.

Cách chúng tôi thực hiện điều này với Apollo Client là tạo phần mềm trung gian Apollo Link. Bắt đầu với việc cài đặtapollo-link-context:

npm install apollo-link-context

Gói này cho phép chúng tôi thêm cơ chế xác thực bằng cách thiết lập ngữ cảnh cho các yêu cầu của chúng tôi.

Chúng ta có thể sử dụng nó trong mã này bằng cách tham khảosetContexthoạt động theo cách này:

import { setContext } from 'apollo-link-context'

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

và khi chúng tôi có Apollo Link mới này, chúng tôi có thểsoạn, biên soạnnó vớiHttpLinkchúng tôi đã có, bằng cách sử dụngconcat()trên một liên kết:

const link = authLink.concat(httpLink)

Đây là mã đầy đủ chosrc/index.jstệp với mã mà chúng tôi có ngay bây giờ:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'
import { setContext } from 'apollo-link-context'
import gql from 'graphql-tag'

import App from ‘./App’

const httpLink = createHttpLink({ uri: https://api.github.com/graphql })

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

const link = authLink.concat(httpLink)

const client = new ApolloClient({ link: link, cache: new InMemoryCache() })

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

CẢNH BÁO ⚠️ 🚧 Hãy nhớ rằng mã này là mộtthí dụcho các mục đích giáo dục và nó hiển thị mã thông báo API GitHub GraphQL của bạn cho thế giới thấy trong mã giao diện người dùng của bạn. Mã sản xuất cần giữ mã thông báo này ở chế độ riêng tư trong phần phụ trợ.

Bây giờ chúng tôi có thể thực hiện yêu cầu GraphQL đầu tiên ở cuối tệp này và truy vấn mẫu này yêu cầu tên và chủ sở hữu của 10 kho lưu trữ phổ biến nhất, với hơn 50 nghìn sao:

const POPULAR_REPOSITORIES_LIST = gql`
{
  search(query: "stars:>50000", type: REPOSITORY, first: 10) {
    repositoryCount
    edges {
      node {
        ... on Repository {
          name
          owner {
            login
          }
          stargazers {
            totalCount
          }
        }
      }
    }
  }
}
`

client.query({ query: POPULAR_REPOSITORIES_LIST }).then(console.log)

Chạy mã này thành công trả về kết quả truy vấn của chúng tôi trong bảng điều khiển trình duyệt:

console log of executed query

Hiển thị kết quả truy vấn GraphQL trong một thành phần

Những gì chúng tôi thấy cho đến nay đã rất tuyệt. Điều thú vị hơn nữa là sử dụng bộ kết quả graphql để hiển thị các thành phần của bạn.

Chúng tôi để Apollo Client gánh nặng (hoặc niềm vui) hoặc tìm nạp dữ liệu và xử lý tất cả những thứ cấp thấp, và chúng tôi có thể tập trung vào việc hiển thị dữ liệu, bằng cách sử dụnggraphqlchất tăng cường thành phần được cung cấp bởireact-apollo.

Thêm cái này vàoApp.jstập tin:

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

const POPULAR_REPOSITORIES_LIST = gql </span><span style="color:#e6db74">{ </span><span style="color:#e6db74"> search(query: "stars:&gt;50000", type: REPOSITORY, first: 10) { </span><span style="color:#e6db74"> repositoryCount </span><span style="color:#e6db74"> edges { </span><span style="color:#e6db74"> node { </span><span style="color:#e6db74"> ... on Repository { </span><span style="color:#e6db74"> name </span><span style="color:#e6db74"> owner { </span><span style="color:#e6db74"> login </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> stargazers { </span><span style="color:#e6db74"> totalCount </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">} </span><span style="color:#e6db74">

const App = graphql(POPULAR_REPOSITORIES_LIST)(props => <ul> {props.data.loading ? ‘’ : props.data.search.edges.map((row, i) => <li key={row.node.owner.login + ‘-’ + row.node.name}> {row.node.owner.login} / {row.node.name}: {’ '} <strong> {row.node.stargazers.totalCount} </strong> </li> )} </ul> )

export default App

Đây là kết quả truy vấn của chúng tôi được hiển thị trong thành phần 😀

The result of our query rendered in the component


Máy chủ Apollo

Máy chủ GraphQL có công việc chấp nhận các yêu cầu đến trên một điểm cuối, diễn giải yêu cầu và tra cứu bất kỳ dữ liệu nào cần thiết để đáp ứng nhu cầu của khách hàng.

Có rất nhiều triển khai máy chủ GraphQL khác nhau cho mọi ngôn ngữ có thể.

Apollo Server là một triển khai máy chủ GraphQL cho JavaScript, đặc biệt là choNode.jsnền tảng.

Nó hỗ trợ nhiều khung Node.js phổ biến, bao gồm:

Apollo Server cung cấp cho chúng ta 3 thứ về cơ bản:

  • cung cấp cho chúng tôi một cách để mô tả dữ liệu của chúng tôi vớilược đồ.
  • cung cấp khuôn khổ chongười giải quyết, là các hàm chúng tôi viết để tìm nạp dữ liệu cần thiết để thực hiện một yêu cầu.
  • tạo điều kiện xử lýxác thựccho API của chúng tôi.

Để bắt đầu, hãy tạo một thư mục có tênappserver, đi vào nó và chạynpm init --yesđể khởi tạo mộtpackage.jsontập tin.

Sau đó chạynpm install apollo-server graphql.

Sân chơi Apollo

Nếu bạn thích một sân chơi trực tuyến, có 2 sân chơi tuyệt vời dành cho Apollo mà tôi giới thiệu.

Đầu tiên được lưu trữ trênTrục trặc, thứ hai trênCodeSandbox.

Đi và phối lại / phân tách các dự án khởi đầu đó để tạo Máy chủ Apollo của riêng bạn.

Máy chủ Apollo Hello World

Tạo ra mộtindex.jstập tin.

Đầu tiên bạn nhậpApolloServergqltừapollo-server:

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

Chúng tôi tạo một định nghĩa giản đồ bằng cách sử dụnggqlnhãn. Định nghĩa giản đồ là một chuỗi ký tự mẫu chứa mô tả về truy vấn của chúng tôi và các loại được liên kết với mỗi trường:

const typeDefs = gql`
  type Query {
    hello: String
  }
`

Angười giải quyếtlà một đối tượng ánh xạ các trường trong lược đồ với các hàm của trình phân giải, có thể tra cứu dữ liệu để trả lời một truy vấn.

Đây là một trình giải quyết đơn giản có chứa hàm phân giải chohellotrường, trả vềHello world!chuỗi:

const resolvers = {
  Query: {
    hello: (root, args, context) => {
      return 'Hello world!'
    }
  }
}

Với 2 yếu tố đó, định nghĩa lược đồ và trình giải quyết, chúng tôi khởi tạo một đối tượng ApolloServer mới:

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

Sau đó, chúng tôi gọi phương thức nghe () trên đối tượng sever và chúng tôi lắng nghe lời hứa sẽ giải quyết, điều này cho biết máy chủ đã sẵn sàng:

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})

Đây là mã đầy đủ cho ví dụ Hello World đơn giản:

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

// Construct a schema, using GraphQL schema language const typeDefs = gql </span><span style="color:#e6db74"> type Query { </span><span style="color:#e6db74"> hello: String </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">

// Provide resolver functions for your schema fields const resolvers = { Query: { hello: (root, args, context) => { return ‘Hello world!’ } } }

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

server.listen().then(({ url }) => { console.log(🚀 Server ready at </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">url</span><span style="color:#e6db74">}</span><span style="color:#e6db74">) })

Bây giờ chạynode index.jsvà từ một cửa sổ bảng điều khiển khác chạy:

$ curl \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{ "query": "{ hello }" }' \
  http://localhost:4000/graphql

Điều này sẽ trả lại cho bạn dữ liệu:

{
  "data": {
    "hello": "Hello world!"
  }
}

Bạn có thể có ứng dụng khách của mình, giao diện với cái này bằng cách sử dụng ví dụ tệp App.js đơn giản này, mà bạn có thể thả vào từ ví dụ API GitHub ở trên:

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

const App = () => ( <Query query={gql</span><span style="color:#e6db74"> { </span><span style="color:#e6db74"> hello </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } > {({ loading, error, data }) => { if (loading) return <p>Loading</p> if (error) return <p>Error :(</p>

  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">hello</span>
}}

</Query> )

export default App

Bạn phải thay đổihttpLinkđi tiểu trongindex.jsnộp vào:

const httpLink = createHttpLink({ uri: 'http://localhost:4000/graphql' })

Các hướng dẫn về graphql khác: