קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
קודקודייל
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
  • קודקודייל
  • מי אתם קודקודייל?
  • קורסים בחינם
  • צרו קשר
  • בניית אתרים
    • וורדפרס
  • נגישות אתרים
  • כל הקטגוריות
    • אנגולר
    • HTML
    • CSS
    • Javascript
    • Typescript
    • NodeJs
    • בלוקציין
ראשי ♦ כלים נוספים ♦ graphQl עוקף את REST בסיבוב? מדריך GQL

graphQl עוקף את REST בסיבוב? מדריך GQL

וינר יאיר 9 באוגוסט 2021 אין תגובות

אם פעם חשבתם ש graphql הוא הפתרון הטוב ביותר לקריאות דטה בייס ככל הנראה צדקדם. יותר ויותר שימושים עם graphql ופחות ב REST. לכן חשוב מאוד להכיר! . אז אם אתה מתכנת צד לקוח או צד שרת, שעוד לא מכירים graphql, הנה פוסט שיכניס אתכם לעניינים ברגל ימין.

מה הוא GQL?

בהגדרה הפשוטה ביותר GQL היא שפה מבוססת שאילתות (מונחת JSON) שמתבצעת על ידי קריאה אחת לAPI ומחזירה מידע בהתאם לשאילתה שלכם. לעומת REST שבחלק גדול מהמקרים מבצע הרבה קריאות. מדובר בשפה שמורכבת משאילות . להלן דוגמה:

אם תרצו לבקש מידע מתוך רשימה של סופרים, רק את שם הסופר וכן את שמות הספרים שאותו כותב כתב. אילו קריאות תדרשו לעשות עם REST ?
ככל הנראה לבקש את כל המידע (לינק) של כל הסופרים,קריאה זו תביא איתה את כל המידע על הסופרים השונים ולא רק את השם, וכן תצטרכו לעשות קריאות נוספות עבור כל כותב ולבקש את רשימת הספרים שלו authors/:id/books

עם GQL זה נראה כך:

query {
  authors {
    id
    name
    books {
    	name  
    }
  }
}

שאליתה זו תביא את המידע המבוקש בקריאה אחת ובלי מידע מיותר. מה שמאפשר גמישות רבה ונוחות.

יתרונות רבים של GQL

  • מהיר יותר
  • קריאה אחת בלבד
  • אפשרות לקבל מידע ספציפי
  • הגדרה של schema
  • פחות טעויות בבקשת המידע או כתיבה
  • קבלת עדכונים ברגע שמידע התעדכן בשרת (באמצעות subscription ולא דרך HTTP )

דוגמא GQL

להלן דוגמה פשוטה וקצרה, דוגמה זו תציג בסיס טוב להיכרות שלכם עם GQL .

נצטרך כמה דברים על מנת לבנות את הדוגמה הזו:

  1. צד לקוח כלשהו – אשתמש ב React
  2. צד שרת כלשהו – אשתמש ב nodejs
  3. מסד נתונים כלשהו – אשתמש ב firebase

נתחיל צד שרת NODEJS ומימוש של GQL

טוב אז נכין צד שרת פשוט עם Nodejs . כל מה שאנחנו צריכים זה קובץ index.js

ולאחר npm init נבצע את ההתקנות הבאות:

npm i express express-graphql graphql

npm install nodemon --save-dev

להלן קובץ package.json מי שרוצה לראות או להשתמש (יש פה כמה נוספים של סטנדרטים)

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon --exec babel-node src/index.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.15.0",
    "@babel/node": "^7.14.9",
    "@babel/preset-env": "^7.15.0",
    "nodemon": "^2.0.12"
  },
  "dependencies": {
    "express": "^4.17.1",
    "express-graphql": "^0.12.0",
    "graphql": "^15.5.1"
  }
}

בהמשך נרים סרבר בסיסי עם express ו GQL:

אחד הדברים היותר נחמדים של לGQL זו סביבה של טסטים מעולה. אפשר לבדוק שאילתות ועוד בקלילות ובממשק UI נעים ואינטואיטיבי. כנסו לקישור שזה עתה יצרתם: localhost:{your_PORT}/graphql . (לא יעבוד לכם כרגע . המשיכו לקרוא)

const express = require('express');
const app = express();

const expressGraphQL = require('express-graphql').graphqlHTTP;

app.use('/graphql', expressGraphQL({
    graphiql: true
}));

app.listen(5001, () => console.log('codcodile GQL tut is running'))

מה זה Schema

טוב אז הקוד שלמעלה לא עובד לכם כי GQL מבקש schema. שזה למעשה אינטרפייס שמגדיר את הדטה בצד השרת, שGQL הולך לעבוד איתו. ולכן צריך לבנות לו schema מסודרת לפי דרישות קפדניות. זה מאד נוח להמשך העבודה עם GQL.

להלן מה קובץ אינדקס עם התוספת של schema:
* זהו הקובץ המלא והסופי של הפויקט דמו. אפרט בהמשך על כל דבר ודבר.

const express = require('express');
const expressGraphQL = require('express-graphql').graphqlHTTP;

const app = express();

const {
    GraphQLSchema,
    GraphQLObjectType,
    GraphQLString,
    GraphQLList,
    GraphQLInt,
    GraphQLNonNull
} = require('graphql');


const authors = [
    { id: 1, name: 'codcodile baby' },
    { id: 2, name: 'codcodile daddy' },
    { id: 3, name: 'codcodile momi' }
]

const books = [
    { id: 1, name: ' simply dummy text of the printing and typesetting industry. Lorem Ipsum has been ', authorId: 1 },
    { id: 2, name: '1960s with the release of Letraset sheets', authorId: 1 },
    { id: 3, name: 'Harry Potter and the Goblet of Fire', authorId: 1 },
    { id: 4, name: 'popular belief, Lorem Ipsum is not simply random', authorId: 2 },
    { id: 5, name: 'using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content', authorId: 2 },
    { id: 6, name: 'sites still in their infancy. Various versions have evolved over the years, sometimes by accident', authorId: 2 },
    { id: 7, name: 'Latin words, consectetur, from ', authorId: 3 },
    { id: 8, name: 'majority have suffered alteration in some form', authorId: 3 }
];


const BookType = new GraphQLObjectType({
    name: 'Book',
    description: 'This represents a book written by an author',
    fields: () => ({
      id: { type: GraphQLNonNull(GraphQLInt) },
      name: { type: GraphQLNonNull(GraphQLString) },
      authorId: { type: GraphQLNonNull(GraphQLInt) },
      author: {
        type: AuthorType,
        resolve: (book) => {
          return authors.find(author => author.id === book.authorId)
        }
      }
    })
  })
  
  const AuthorType = new GraphQLObjectType({
    name: 'Author',
    description: 'This represents a author of a book',
    fields: () => ({
      id: { type: GraphQLNonNull(GraphQLInt) },
      name: { type: GraphQLNonNull(GraphQLString) },
      books: {
        type: new GraphQLList(BookType),
        resolve: (author) => {
          return books.filter(book => book.authorId === author.id)
        }
      }
    })
  })
  
  const RootQueryType = new GraphQLObjectType({
    name: 'Query',
    description: 'Root Query',
    fields: () => ({
      book: {
        type: BookType,
        description: 'Current Book',
        args: {
          id: { type: GraphQLInt }
        },
        resolve: (parent, args) => books.find(book => book.id === args.id)
      },
      books: {
        type: new GraphQLList(BookType),
        description: 'List of All Books',
        resolve: () => books
      },
      authors: {
        type: new GraphQLList(AuthorType),
        description: 'List of All Authors',
        resolve: () => authors
      },
      author: {
        type: AuthorType,
        description: 'Current Author',
        args: {
          id: { type: GraphQLInt }
        },
        resolve: (parent, args) => authors.find(author => author.id === args.id)
      }
    })
  })
  
  const RootMutationType = new GraphQLObjectType({
    name: 'Mutation',
    description: 'Root Mutation',
    fields: () => ({
      addBook: {
        type: BookType,
        description: 'Add book',
        args: {
          name: { type: GraphQLNonNull(GraphQLString) },
          authorId: { type: GraphQLNonNull(GraphQLInt) }
        },
        resolve: (parent, args) => {
          const book = { id: books.length + 1, name: args.name, authorId: args.authorId }
          books.push(book)
          return book
        }
      },
      addAuthor: {
        type: AuthorType,
        description: 'Add author',
        args: {
          name: { type: GraphQLNonNull(GraphQLString) }
        },
        resolve: (parent, args) => {
          const author = { id: authors.length + 1, name: args.name }
          authors.push(author)
          return author
        }
      }
    })
  })
  
  const schema = new GraphQLSchema({
    query: RootQueryType,
    mutation: RootMutationType
  })



app.use('/graphql', expressGraphQL({
    schema: schema,
    graphiql: true
}));

app.listen(5001, () => console.log('codcodile GQL tut is running'))

טוב אז יש לנו פה כמה דברים חשובים מאד שתדעו! והם:

  1. GraphQLObjectType – מגדיר את הטייפים של המידע שלכם.
  2. GraphQLSchema – מגדיר את ה schema.
  3. GraphQLString , GraphQLList ,GraphQLInt , GraphQLNonNull – טייפים של GQL נוספים .
  4. Query
  5. Mutation

GraphQLObjectType

טייפ זה חיוני מאד בעבודה עם GQL , למשל אפשר לראות בדוגמה שלנו שהוא מגדיר את הטייפים וגם מאפשר לייצר טייפים בתוך טייפים כמו למשל RootQueryType שהוא הראשי שאוסף לתוכו את הטייפים כגון: AuthorType ,

GraphQLSchema

בסופו של דבר כל ההגדרות של המידע נשפכות לתוך ה Schema שהוא צריך להיות מסוג GraphQLSchema . כמו בקוד שלנו בשורה 130.

GraphQLString , GraphQLList ,GraphQLInt , GraphQLNonNull

טייפים חיוניים לעבודה עם GQL . שימו לב בקוד שלנו היכן בחרנו להשתמש בהם. למשל ID יהיה מטייפ GraphQLInt בעוד משיידע שהוא סטרינגי יהיה GraphQLString . הטייפ GraphQLNonNull מאפשר לנו להגדיר ערך שלא יכול להיות null.

Query

אפשר לראות שהחל משורה 65 בקוד שלנו משהו מעניין מאוד. למעשה זה חלק מהותי בעבודה עם GQL . נבחר להגדיר סוג של מידע שהינו עבור שאילתות לקבלת המידע ולכן ניתן לאשם 'Query' (יכול להיות כל שם שתבחרו בגדול). ואז נגדיר את הסדרות ואופי הבאת הנתונים למשל בשורה 69 נרשום book שמייצג עבורנו כי אנחנו רוצים לקבל מידע של book אחד בלבד. ולכן נרצה להוסיף args שמביא מידע ייחודי לספר (id במקרה הזה) ונמשיך לשורה 75 ונשתמש בפונקציה חשובה לא פחות בשם resolve שלמעשה תעשה פעולה שאנחנו מכירים של find by id ותחזיר את המדיע.
בהמשך נגיד לשורה 77 , שמה נראה כי אנחנו מגדירים ערך של books , כלומר את כל המידע של הספרים. אפשר לראות שיש שימוש בטייפ של רשימה : GraphQLList.
והפעם resolve יחזיר את כל הספרים.

בהמשך תראו משהו מאד דומה עבור authors , author

Mutation

מוטשיין מוטשיין מוטיישן… מאפשר לנו לכתוב או למחוק מהדטה בייס . בדוגמה שלנו אפשר לראות למשל בשורה 89 והילך כיצד לבצע פונקציה שיודעת לכתוב ספר חדש \ כותב חדש לדטה בייס.

נמשיך עם צד לקוח REACT וההתקנות של GQL .

לאחר סיום ההתקנה של React נתכין את הדברים הבאים:

npm install @apollo/client graphql

ועכשיו נתחיל במימוש בסיסי של GQL ו APOLLO בapp.js

import './App.css';
import Books from './books';

import { InMemoryCache, ApolloProvider, createHttpLink, ApolloClient } from '@apollo/client';


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


function App() {
  
  return (
   <ApolloProvider client={client}>
     <Books />
   </ApolloProvider>
  );
}

export default App;

apollo/client עוזר לנו לממש GQL בצד לנוח. באתר שלהם אפשר לראות המון דוגמאות ודוקומנטציה סופר נוחה וקלה להבנה.

לפני שנחשוף את הקומפוננטה של books נעבור למשהו יותר חשוב , כיצד אנו מושכים את המידע בעזרת שאילתה של GQL
זה נראה כך , נכין קובץ נפרד לשאילתות לשם הנוחות:

import { gql } from '@apollo/client';

const GET_ALL_BOOKS_DATA = gql`
query {
    books {
    id
    name
    author {
    	name  
    }
  }
}
`;
export  {GET_ALL_BOOKS_DATA};

נעשה שימוש בשאילתא הזו בקומפוננטה של books הרי השיאלתא מביאה את המידע של books

וכן עושים זאת:

import React , {useEffect, useState} from 'react'
import {useQuery} from '@apollo/client';
import {GET_ALL_BOOKS_DATA} from './graphql/queries';
import Book from './book';

export default function Books() {
    
    const { loading, error, data } = useQuery(GET_ALL_BOOKS_DATA);
    const [state, setstate] = useState(null);
    useEffect(() => {
        if(loading){
            
        }else{
            setstate(displayLaunches(data));
        } 
    },[data])

    function displayLaunches(data){
        return data.books.map((book)=>{
            return  (<Book key={book.id} bookData={book} />)
                })
        }
    return (
        <div>
            {state}
        </div>
    )
}

useQuery – הפונקציה שתטפל בשאילתא ותחזיר לנו את המידע מוכן. נעש שימוש בuseeffect בשביל לקבל את המידע ברגע שיתעדכן.

וזהו נוכל להציג את המידע שמגיע מהשאילתא בעזרת קומפוננטה פשוטה book.

import React from 'react'

export default function Book({bookData}) {
    return (
        <div>
            {bookData.name}
            {bookData.author.name}
        </div>
    )
}

סיכום מדריך GQL

כמובן שזה לא הכל. זה למעשה על קצה המזלג ביכולותיו של GQL . אך זהו שיעור בסיסי וחשוב מאד להכיר וכל על מנת להמשיך ולהעמיק לתוך GQL ונצל את היכולות הגדולות שלו אצלכם בקוד. בהמשך צפו לפוסטים נוספים בGQL ושם נעמיק יותר . לרוב אשלב אותו בפרויקטים של מדריכים וכדומה. בהצלחה תנינים 🐊🐊🐊

פוסטים קשורים:

תקלה בריאקט בקינפוג עם sassבעיות נפוצות ב-react | קינפוג עם sass מדריך react | ריאקט | איך מעבירים מידע בין קומפננטות באמצעות propsמדריך react | ריאקט | איך מעבירים מידע בין קומפננטות באמצעות props מדריך ריאקט – classes, functional component & hooks וורדפרס custom post typeקורס בניית אתרים בוורדפרס – Custom Post types
GQL graphQL reactjs REST מדריך GQL מדריך ריאקט

אודות המחבר

יאיר וינר להציג את כל הפוסטים של וינר יאיר


« פוסט קודם
פוסט הבא »

השארת תגובה

ביטול

חיפוש באתר
בחירת העורכים
29 בדצמבר 2023 עידן יצחקי

שדה טקסט עשיר עם תמונות

אתם הולכים להיות מופתעים עד כמה HTML יכול להיות חכם ולבצע משהו כל כך מורכב, שאם אנחנו היינו רוצים ליצור

1 באוקטובר 2021 עידן יצחקי

איך למשוך דינמית favicon של אתרים אחרים ב-JS

בפוסט זה נראה איך אפשר על פי לינקים בדף למשוך את ה-favicon מהדומיין שלהם באופן דינמי, בדיקה של תקינות התמונה

פופולרי
Javascript functions – היכרות עם סוגי פונקציות
Javascript
21 בדצמבר 2024 אין תגובות
Nested routing in angular standalone component
Typescript
15 בנובמבר 2024 תגובה אחת
בחרו לפי תגיות
angular blockchain css ethers express front-end fullstack GQL html javascript next js nextjs nodejs react hooks reactjs solidity webgl אנגולר בלוקציין וורדפרס לימודי אנגולר לימודי וורדפרס לימוד ריאקט מדריך front-end מדריך GQL מדריך אנגולר מדריך וורדפרס מדריך חינם react מדריך ריאקט מפתח בלוק מפתח בלוקציין מתכנת front-end מתכנת בלוקציין מתכנת פרונט סולידיטי קורס front end קורס fullstack קורס nextjs קורס אנגולר קורס בלוקציין קורס בלוקציין בחינם קורס סולידיטי קורס ריאקט קורס תכנות קורס תכנות בחינם
סינון על פי קטגוריות
CSS fullstack HTML IIS Javascript nodeJs SEO Typescript אנגולר בלוקציין בניית אתרים וורדפרס חיפוש עבודה כלים נוספים כללי נגישות קורסים ריאקט תלת מימד תקלות ופתרונות
צור קשר
כל הזכויות שמורות לקודקודייל
ליצירת קשר: @ קודקודייל
גלילה לראש העמוד
דילוג לתוכן
פתח סרגל נגישות כלי נגישות

כלי נגישות

  • הגדל טקסטהגדל טקסט
  • הקטן טקסטהקטן טקסט
  • גווני אפורגווני אפור
  • ניגודיות גבוההניגודיות גבוהה
  • ניגודיות הפוכהניגודיות הפוכה
  • רקע בהיררקע בהיר
  • הדגשת קישוריםהדגשת קישורים
  • פונט קריאפונט קריא
  • איפוס איפוס