ساخت یک فول استک اپ با استفاده از React، NodeJS و Apollo GraphQL

ترجمه و تالیف : ابوالفضل باغشاهی
تاریخ انتشار : 27 آبان 99
خواندن در 3 دقیقه
دسته بندی ها : برنامه نویسی

Apollo Client یک کتاب‌خانه‌ی state management (مدیریت استیت) کامل و جامع است و ابزاریست قدرتمند برای استفاده هم در بک اند و هم در فرانت اند. در این مقاله قصد داریم از این ابزار برای ساخت یک Apollo GraphQL Server توسط NodeJS استفاده کنیم. بعد از آن نیز به استفاده از داده‌های مورد نیازمان در سمت کلاینت (به وسیله‌ی React JS) خواهیم پرداخت.

اگر شما به دنیای GraphQL تازه وارد هستید، پیشنهاد می‌کنم که این آموزش را مطالعه کنید؛ در غیر این‌صورت به مطالعه‌ی ادامه‌ی این مقاله بپردازید.

مطالب این مقاله به شکل فهرست‌وار

  • ساخت سرور با استفاده از Node، Apollo و GraphQL
  • GraphQL Schema
  • GraphQl resolvers
  • ساخت سرور Apollo
  • ساخت اپ سمت کلاینت با استفاده از React
  • اتصال React به Apollo
  • واکشی (fetch) داده‌ها
  • نمایش داده‌ها

نکته: در تمام این طول این آموزش می‌توانید به جای استفاده از پکیج منیجر yarn، از npm استفاده کنید.

1- ساخت سرور با استفاده از Node، Apollo و GraphQL

در این آموزش از Github API برای محیا کردن داده‌هایمان استفاده می‌کنیم و عملیات نمایش این داده‌ها نیز توسط سرور graphql که با استفاده از Node و Apollo ساخته شده است، صورت می‌گیرد.

در مرحله‌ی اول نیاز است که دستور زیر را در ترمینال اجرا کنیم تا یک پروژه‌ی نود جی اسی جدید را بسازیم:

yarn init

وقتی این دستور به طول کامل اجرا شد، حال می‌توانیم پکیج‌های موردنیازمان را هم با استفاده از دستور زیر، نصب کنیم:

  yarn add apollo-server graphql axios

حال تمام ابزارهای مورد نیازمان برای ایجاد سرور مورد نظر را داریم. پس بیاید یک فایل جدید با عنوان app.js در ریشه‌ی (روت) پروژه‌ی خود، بسازیم که درواقع نقطه ورود به سرور ما است.

بعد از آن باید یک الگوی GraphQL ای بسازیم که نمایان‌گر نحوه‌ی نمایش داده‌ها باشد.

2- GraphQL Schema

یکSchema  یا طرح‌واره، شکل نمودار داده‌های ما را توصیف می‌کند؛ در واقع این Schema، مجموعه‌ای است از انواع مختلف داده به همراه فیلدهای مورد نیاز هر کدام که از دیتا استور بک اند به دست آمده است. پس بیایید یک Schema جدید در 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ی گیت هاب استفاده کنیم. ما تنها به id (که کلید ارجاع reference key ما در اپلیکیشن ری اکت مان است) به همراه login و avatar_url نیاز داریم؛ همچنین دارای یک query با نام users نیز هستیم که آرایه‌ای از کاربران را به ما بر می‌گرداند.

حال که طرح‌واره‌ی گرف کیوال (GraphQL schema) خود را ساخته‌ایم، باید resolverهای مربوطه را نیز برای به تکمیل رساندن عملیات کوئری زدن، تشکیل دهیم.

3- GraphQl resolvers

Resolver مجموعه‌ای از فانکشن‌هاست که به تولید پاسخ (ریسپانس) مربوط به یک درخواست (کوئری) GraphQL ای، کمک می‌کند؛ پس در مرحله‌ی بعدی باید یک resolver در فایل app.js به وجود بیاوریم:

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

یک resolver نیاز دارد تا از طریق نام با یک الگو، جفت شود. در نتیجه در این مثال users اشاره به کوئری users دارد که در الگوی ما تعریف شده است. در واقع این فانکشنی است که داده را از API به کمک axios واکشی (fetch) می‌کند. این فانکشن مطابق انتظار، id, login و avatar_url را باز خواهد گرداند.

این عملیات می‌تواند زمان‌بر باشد و برای تکمیل، طول بکشد. به همین دلیل است که از async await استفاده کرده‌ایم تا از این بابت دچار مشکل نشویم.

با کارهایی که تا این‌جا انجام داده‌ایم، وقت آن رسیده است که در بخش بعدی به ساخت Apollo Server بپردازیم.

4- ساخت سرور Apollo

اگر به یاد داشته باشید، ما در app.js، ApolloServer را از پکیج Apollo-server ایمپورت کرده بودیم که یک constructor است و یک شی را به عنوان ورودی (آرگومان) خود دریافت می‌کند. این آبجکت یا شی، باید شامل schema و resolver باشد تا بتواند سرور را بسازد.

با استفاده از ApolloServer فایل app.js را کمی گسترش می‌دهیم:

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

در این‌جا به عنوان پارامتر، آبجکتی را پاس می‌دهیم که شامل schema و resolverای است که پیش‌تر در app.js تعریف کرده‌ایم تا آپولو سرور ما، متناسب با این دو مورد باشد. با طی این مرحله، شما یک سرور کارآمد و آماده به کار دارید.

شما می‌توانید با استفاده از این سرور و با دستور زیر، به ارسال کوئری‌ها و درخواست‌های خود با کمک GraphQL بپردازید:

  yarn start

حال می‌توانید برای نمایش نتیجه‌ی کارهای خود تا به این مرحله، به local host خود و آدرس http://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("https://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 امان داریم تا سرور راه‌اندازی شود.

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

البته توجه داشته باشید که برای استفاده از nodemon نیاز به نصب پکیج آن (همانند کاری که در ابتدای این آموزش برای آپولو سرور کردیم) دارید.

حال در این نقطه شما دارای یک سرور برای واکشی یا فچ داده‌ها از API گیت‌هاب هستید. پس بیایید به سمت کلاینت رفته و به استفاده از داده‌های این API در سمت کاربران، بپردازیم.

5- ساخت اپ سمت کلاینت با استفاده از React

اولین کاری که در این وهله باید انجام دهیم، اجرای دستور زیر برای ساخت یک پروژه‌ی جدید ری‌اکت است:

npx create-react-app client-react-apollo

سپس نیاز به نصب پکیج‌های Apollo و GraphQL داریم:

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

حال می‌توانیم با ایجاد تغییرات در فایل index.js پروژه‌ي ری‌اکت خود، به اتصال آپولو به اپ ری‌اکتی خود بپردازیم.

6- اتصال 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: 'https://7sgx4.sse.codesandbox.io'
})


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

serviceWorker.unregister();

همان‌طور در بالا مشهود است، کار را با ایمپورت کردن ApolloClient و ApolloProvider شروع کرده‌ایم.

آپولو کلاینت، در اطلاع‌رسانی به Apollo در رابطه با URL ای که باید برای واکشی داده استفاده کند، به کار می‌آید. اگر هم هیچ uri ای به آپولو کلاینت پاس داده نشود، به شکل پیش‌فرض، تنها نام دامنه‌ی کنونی به علاوه‌ی /graphql  می‌شود.

آپولو پرووایدر نیز انتظار دارد که آبجکت کلاینت را دریافت کند تا بتواند به اتصال آپولو به ری‌اکت منجر شود.

حال می‌توانیم در مرحله‌ی بعد به ساخت کامپوننتی بپردازیم که بتواند داده‌ه‌های مورد نظرمان را به نمایش در آورد.

7- واکشی fetch)) داده‌ها

در این مرحله فایل 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
    }
  }

حال یک کوئری graphQL ساده داریم که به واکشی داده‌ها می‌پردازد. این کوئری بعدا به useQuery پاس داده خواهد شد تا به Apollo نشان دهد که چه داده‌هایی را باید fetch کند.

const User = ({ user: { login, avatar_url } }) => (
  <div className="Card">
    <div>
      <img alt="avatar" className="Card--avatar" src={avatar_url} />
      <h1 className="Card--name">{login}</h1>
    </div>
    <a href={`https://github.com/${login}`} className="Card--link">
      See profile
    </a>
  </div>
)

8 - نمایش داده‌ها

هوک (hook) useQuery که توسط آپولو برای دریافت کوئری‌های GraphQL طراحی‌ شده‌است، سه حالت (استیت) را می‌تواند برگرداند: loading , error, data (در حال بارگذاری، خطا، داده)

function App() {
  const { loading, error, data } = useQuery(GET_USERS)

  if (error) return <h1>Something went wrong!</h1>
  if (loading) return <h1>Loading...</h1>

  return (
    <main className="App">
      <h1>Github | Users</h1>
      {data.users.map(user => (
        <User key={user.id} user={user} />
      ))}
    </main>
  )
}

export default App

اگر داده‌ها به شکلی موفقیت‌آمیز واکشی شده‌باشند، ما آن‌ها را به کامپوننت user پاس ‌می‌دهیم و در غیر این‌صورت، اعلام بروز خطا می‌کنیم.

در زیر می‌توانید فایل 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
    }
  }
`

const User = ({ user: { login, avatar_url } }) => (
  <div className="Card">
    <div>
      <img alt="avatar" className="Card--avatar" src={avatar_url} />
      <h1 className="Card--name">{login}</h1>
    </div>
    <a href={`https://github.com/${login}`} className="Card--link">
      See profile
    </a>
  </div>
)

function App() {
  const { loading, error, data } = useQuery(GET_USERS)

  if (error) return <h1>Something went wrong!</h1>
  if (loading) return <h1>Loading...</h1>

  return (
    <main className="App">
      <h1>Github | Users</h1>
      {data.users.map(user => (
        <User key={user.id} user={user} />
      ))}
    </main>
  )
}

export default App

بالاخره به نقطه‌ی پایانی این آموزش رسیدیم و شما توانسته‌اید یک اپ فول استک  Apollo GraphQLرا به‌وسیله‌ی React و NodeJS بسازید.

برای پیش‌نمایش سرور Apollo GraphQL می‌توانید به این‌جا بروید.

برای پیش‌نمایش سرور React App می‌توانید به این‌جا بروید.

منبع

گردآوری و تالیف ابوالفضل باغشاهی
آفلاین
user-avatar

Front-End

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید