Menu Close

React : GraphQL เบื้องต้น (ตอนที่ 2/2)

มาถึงบล็อกตอนที่ 2 ของเรื่อง GraphQL เบื้องต้น ในตอนที่ 1 เราได้รู้เรื่องเกี่ยวกับ GraphQL การเตรียมข้อมูลและ API และเครื่องมือที่ใช้สำหรับเขียนโปรแกรม React เพื่อเรียกใช้งาน GraphQL กันไปแล้ว ในบล็อกนี้จะมาต่อกันที่วิธีการเขียนโปรแกรม React ในการเรียกใช้งาน GraphQL เบื้องต้น สามารถทำได้อย่างไร โดยเราจะเขียนโค้ดโดยใช้โปรแกรมบน codesandbox.io

ทำความรู้จักและเตรียมข้อมูลในรูปแบบ GraphQL

React : GraphQL เบื้องต้น (ตอนที่ 1/2)

ติดตั้งไลบรารี่ให้พร้อมใช้งาน GraphQL

npm install @apollo/client graphql

เริ่มต้นเขียนโปรแกรม React

1. import {ApolloClient, InMemoryCache, ApolloProvider, useQuery, gql} from “@apollo/client” ที่ App.js

2. สร้างตัวแปร client ด้วยคลาส ApolloClient ตรง uri ให้ใช้ Content API URL จากบทความตอนที่ 1 หรือ API ที่เตรียมไว้แล้วได้เลย

import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  useQuery,
  gql
} from "@apollo/client";

const client = new ApolloClient({
  uri:
    "https://api-ap-northeast-1.graphcms.com/v2/cktefu37f2up601z78q95htoq/master",
  cache: new InMemoryCache()
});

3. นำ ApolloProvider ไปครอบ Component ใน App เอาไว้ (**อาจจะทำการครอบ ApolloProvider ไว้ที่หน้า index.js ก็ได้)

...

const App = () => {
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>ตัวอย่างโปรแกรม React เรียกใช้งาน GraphQL</h2>
      </div>
    </ApolloProvider>
  );
};

export default App;

4. สร้าง VocabList Component ในไฟล์ App.js (เขียนในไฟล์เดียวกันไปก่อนเพื่อให้ดูง่ายๆ)

const VocabList = () => {

  return (
  <div>
    <h3>รายการคำศัพท์</h3>
  </div>
  )
}

5. เรียกใช้ VocabList ใน App Component

const App = () => {

  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>ตัวอย่างโปรแกรม React เรียกใช้งาน GraphQL</h2>
        <VocabList />
      </div>
    </ApolloProvider>
  );
};

export default App;

6. สร้าง Fech data ด้วยคำสั่ง graphql ใน VocabList Component (ไฟล์ App.js)

คำสั่ง graphql นี้เราได้ทำการทดสอบมาแล้ว และ property ที่ต้องการเรียกดู ได้แก่ id, vocab และ meaning

query VocabsQuery {
  vocabs {
    id
    vocab
    meaning
  }
}

โค้ดใน VocabList Component จะแก้ไขเป็น

const VocabList = () => {
  const vocabs = gql`
    query VocabsQuery {
      vocabs {
        id
        vocab
        meaning
      }
    }
  `;

  return (
  <div>
    <h3>รายการคำศัพท์</h3>
  </div>
  )
}

7. ใน VocabList Component หลังจากที่ประกาศตัวแปร vocabs ที่เป็น graphql command แล้ว ให้ประกาศตัวแปรในการ ดึงข้อมูล ดังนี้

...
 const { loading, error, data } = useQuery(vocabs);
  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error :(</p>;

  return (
  <div>
    <h3>รายการคำศัพท์</h3>
    <div>
      {
        data && data?.vocabs?.map(i => <p key={i.id}>{i.vocab} = {i.meaning}</p>)
      }
    </div>
  </div>
  )
}

8. หลังจากแก้ไข VocabList Component ให้สามารถโหลดข้อมูลจาก graphQL Command ได้แล้ว เราจะสามารถโหลดข้อมูลได้ และได้รับข้อมูลแสดงผลออกทางหน้าจอได้สำเร็จ

ผลลัพธ์การโหลดข้อมูลด้วย GraphQL

รายละเอียดโค้ดโปรแกรมการดึงข้อมูลผ่าน GraphQL Command (VocabList Component)

โค้ดโปรแกรมของ VocabList Component

ส่วนที่ 1 การประกาศ graphql command ที่ทำการเรียกข้อมูลทั้งหมดมาแสดง โดยจะแสดงฟิวด์ id, vocab, meaning ในแต่ละรายการ

gql เป็นคำสั่งเพื่อระบุว่าโค้ดใน ` … ` เป็นคำสั่ง graphql เช่นตามตัวอย่างจะเป็นคำสั่ง query ที่ตั้งชื่อว่า VocabsQuery ถ้าค้นข้อมูลออกมาได้แล้ว ข้อมูลจะอยู่ในตัวแปร vocabs ตามโครงที่กำหนดไว้ในคำสั่ง

ส่วนที่ 2 การประกาศตัวที่ใช้ควบคุมการแสดงผลการดึงข้อมูล โดยจะใช้ hook function คือ useQuery(คำสั่ง graphql)

const { loading, error, data } = useQuery(vocabs);

useQuery จะส่งค่ากลับมาจาก hook function จำนวน 3 ค่า ดังนี้

  • loading คือ สถานะกำลังโหลดข้อมูลอยู่
  • error คือ ข้อผิดพลาดจากการโหลดข้อมูล
  • data คือ ข้อมูลที่โหลดมาเรียบร้อยแล้ว

ดังนั้น ในโค้ดบรรทัดถัดมา เราจะเขียนดักการแสดงผล ขณะที่กำลังโหลด และ เกิดเออเรอ ตามโค้ดนี้

if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;

ส่วนที่ 3 เป็นส่วนการแสดงรายการข้อมูล เมื่อโปรแกรมโหลดข้อมูลสำเร็จแล้ว ข้อมูลจะถูกเก็บในตัวแปร data และถ้าเราต้องการเรียกใช้งาน รายการข้อมูล จะต้องใช้ data.vocabs เนื่องจากเรากำหนดตัวแปร vocabs ในโครงสร้างของคำสั่ง graphql เอาไว้

วิธีการแสดงผล ให้แสดงผลภายในแท็ก <p> และใช้ฟังก์ชัน map ของอาเรย์เป็นตัวจัดการการแสดงผลของสมาชิกอาเรย์ทุกตัว


ปรับแต่งเพิ่มเติมการค้นหาคำศัพท์

ในส่วนนี้เพิ่มให้เป็นพิเศษ หากทำตามขั้นตอนข้างต้นมาจนจบ เราจะสามารถเรียกใช้ข้อมูลที่ดึงผ่าน graphql ได้สำเร็จเรียบร้อยแล้ว

คราวนี้เรามาเพิ่มส่วนการค้นหาข้อมูล เพื่อไปดึงข้อมูลมาใหม่บ้าง โดยการค้นข้อมูลใน graphql จะใช้รูปแบบคำสั่ง ดังนี้

query VocabsQuery {
  vocabs(where: {vocab_contains: "___คำที่ต้องการค้น___"}) {
    meaning
    id
    vocab
  }
}

โดยเราจะเพิ่ม Text Input เพื่อรับค่าการค้นคำศัพท์ภาษาอังกฤษใน ฟิวด์ vocab และเรียกดึงข้อมูลใหม่ เป็นดังนี้

  • สร้าง SearchText Component มาใช้ในการกรอกคำศัพท์ที่ต้องการค้นหา
const SearchText = ({ text = "", setText }) => {
  return (
    <div>
      <input
        type="text"
        placeholder="ค้นหาศัพท์"
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
    </div>
  );
};
  • สร้าง [text, setText] = useState(“”) กำหนดค่าคำศัพท์ที่ใช้ค้นหาไว้ใน App Component เพื่อส่งไปยัง SearchText และ VocabList Component
const App = () => {
  const [text, setText] = useState("");
  
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h2>ตัวอย่างโปรแกรม React เรียกใช้งาน GraphQL</h2>
        <SearchText text={text} setText={setText} />
        <VocabList text={text} />
      </div>
    </ApolloProvider>
  );
};
  • แก้ไขคำสั่ง graphql ใน VocabList Component ให้สามารถค้นข้อมูลผ่านคำสั่ง graphql ได้
const VocabList = ({ text = "" }) => {
  const vocabs = gql`
    query VocabsQuery {
      vocabs(where: {vocab_contains: "${text}"}) {
        id
        vocab
        meaning
      }
    }
  `;

...

เมื่อทำการแก้ไขเสร็จแล้วก็จะมีกล่อง Input ให้เราใส่คำศัพท์ เพื่อค้นหาเข้าไปได้

โค้ดโปรแกรมสำเร็จจะแชร์ใน codesandbox ดังนี้

สรุป

การดึงข้อมูลด้วย GraphQL จากลักษณะคำสั่งแล้ว จะบริการและอำนวยความสะดวกให้กับ client สามารถจะดึงข้อมูลได้ตามความต้องการ สามารถสร้างคำสั่ง query ข้อมูลตามเงื่อนไขต่างๆ ได้ และใน React หากต้องการจะใช้ GraphQL จะต้องติดตั้งไลบรารี่เพิ่มเติมได้แก่ @apollo/client และ graphql

ในไลบรารี่ @apollo/client เราต้องทำการสร้าง ApolloProvider ขึ้นมาใช้งานก่อน โดยค่าตั้งค่าจะใช้ client ซึ่งจะมีการกำหนด API URL ที่ให้บริการข้อมูลแบบ GraphQL เข้าไป และ InMemoryCache() จะเป็นตัวเก็บผลลัพธ์การค้นหาที่ซ้ำเดิม ทำให้โปรแกรมไม่ต้องเรียก API ซ้ำอีกครั้ง เราสามารถปรับแต่งค่า config ของ cache นี้ได้ด้วย อ่านเพิ่มเติม

การเรียกใช้งาน จะใช้ฟังก์ชัน useQuery ซึ่งเป็น hook function ในการดึงข้อมูลจาก GraphQL Command ค่าส่งคืนมาจะมี 3 ค่า ได้แก่ loading, error และ data

ผลลัพธ์การดึงข้อมูลด้วย GraphQL จะได้ค่าออกมาเป็น JSON Object โดยเราจะต้องเรียกใช้ค่านั้นผ่าน ตัวแปรที่เรากำหนดไว้ในโครงสร้างคำสั่ง GraphQL ที่เรียกไป เช่นในตัวอย่าง หากต้องการเรียกใช้งานข้อมูลที่ดึงมาแล้ว จะต้องเรียกใช้ผ่านตัวแปร data.vocabs

คำสั่งในการดึงข้อมูลของ GraphQL มีหลากหลายลักษณะ ในตัวนี้ยกตัวอย่าง 2 แบบ คือ คำสั่งที่ค้นทั้งหมดแบบไม่มีเงื่อนไข และ เงื่อนไข where: vocab_contains อ่านเพิ่มเติม

GraphQL ไม่ได้ทำได้แค่เพียงดึงข้อมูลเท่านั้น แต่การกระทำแบบ CRUD (create, read, update, delete) กับข้อมูลสามารถทำได้ทุกอย่าง อีกทั้งยังมีการกำหนด Authentication การเข้าใช้งาน เหมือนกับเราใช้ Rest API อ่านเพิ่มเติม

จะเห็นได้ว่าเรื่องของ GraphQL ยังมีความน่าสนใจอีกมาก หากเพื่อนๆ สนใจลองอ่านเพิ่มเติมได้ที่ https://graphql.org/learn/ และ https://www.apollographql.com/docs/react/

อ้างอิง

  1. https://www.apollographql.com/docs/react/get-started/
  2. https://www.apollographql.com/docs/react/caching/cache-configuration/
  3. https://graphql.org/learn/queries/
  4. https://graphql.org/learn/authorization/

Posted in react

ใส่ความเห็น