בפיתוח אינטרנט, אופטימיזציה והתרחבות של אפליקציות היו תמיד בעיה. React.js זכתה להצלחה חריפה בפיתוח חזיתי ככלי שמספק דרך חזקה ליצירת ממשקי משתמש. אך הדבר מורכב עם התרחבות האפליקציות, במיוחד כאשר מדובר במספר רב של נקודות קצה של REST API. דאגות כמו יתר-קריאה, שבה דרושים נתונים נוגדים, עשויים להיות מקור לבקבוקיות בביצועים ולחוויית משתמש לא איכותית.
בין הפתרונות לאתגרים אלו היא החלטה לאמץ את השימוש ב־GraphQL עם אפליקציות React. אם לשרת האחורי שלך יש מספר רב של נקודות קצה של REST, אז הכנסת שכבת GraphQL שקוראת פנימית את נקודות הקצה של ה־API שלך יכולה לשפר את האפליקציה שלך מייתר-קריאה ולזרום את האפליקציה שלך בחזית העבודה. במאמר זה, תמצא כיצד להשתמש בזה, היתרונות והחסרונות של הגישה הזו, אתגרים שונים, וכיצד לטפל בהם. נחקור גם יותר בעומק בדוגמאות מעשיות של כיצד GraphQL יכולה לעזור לך לשפר את הדרכים שבהן אתה עובד עם הנתונים שלך.
יתר-קריאה ב־REST APIs
ב־REST APIs, יתר-קריאה מתרחשת כאשר כמות הנתונים שה־API מספק ללקוח היא יותר מאשר מה שהלקוח דורש. זהו בעיה נפוצה ב־REST APIs, שלעיתים תמיד מחזירים סכימת אובייקט או תגובה קבועה. כדי להבין יותר טוב את הבעיה הזו, נביט בדוגמה.
שקול דף פרופיל משתמש שבו דרוש להציג את שם
ואת אימייל
של המשתמש בלבד. עם API טיפי, קריאת הנתונים של המשתמש עשויה להיראות כך:
fetch('/api/users/1')
.then(response => response.json())
.then(user => {
// Use the user's name and profilePicture in the UI
});
תגובת ה־API תכיל נתונים מיותרים:
{
"id": 1,
"name": "John Doe",
"profilePicture": "/images/john.jpg",
"email": "[email protected]",
"address": "123 Denver St",
"phone": "111-555-1234",
"preferences": {
"newsletter": true,
"notifications": true
},
// ...more details
}
על מרוב היותר, האפליקציה מחייבת רק את שדות השם והדוא"ל של המשתמש, אך ה- API מחזיר את אובייקט המשתמש במלואו. המידע הנוסף זה יכול להגדיל את גודל החבילה, לצרוך עוד רוחב פס, ולספק לאט את האפליקציה בסופו של דבר כאשר היא משתמשת במכשיר עם משאבים מוגבלים או חיבור רשת איטי.
GraphQL כפתרון
GraphQL פותר בעיה זו באמצעות הרשאת לקליינטים לבקש בדיוק את הנתונים שהם זקוקים אליהם. על ידי שילוב שרת GraphQL באפליקציה שלך, אתה יכול ליצור שכבת גישה למידע גמישה ויעילה שמתקשרת עם ה- REST API הקיימים שלך.
איך זה עובד
1. התקנת שרת GraphQL
אתה מכניס שרת GraphQL שמשמש כאמצעי בין קרן ה- React שלך וה- REST API.
2. הגדרת סכמה
אתה מגדיר סכמת GraphQL שמציינת את סוגי הנתונים והשאילתות שנדרשים על ידי קרן ה- frontend שלך.
3. יישום מקרים פתרון
אתה מיישם מקרי פתרון בשרת ה- GraphQL שמביאים נתונים מה- REST API ומחזירים רק את השדות הדרושים.
4. אינטגרציה עם הקדמה
אתה מעדכן את האפליקציה שלך ב- React כך שתשתמש בשאילתות GraphQL במקום בקריאות ישירות ל- REST API.
גישה זו מאפשרת לך לייעל את אחזור הנתונים מבלי לעבור על תשתיות השרת שלך שכבר קיימות.
יישום GraphQL באפליקציה של React
בואו נסתכל על כיצד להקים שרת GraphQL ולשלב אותו בתוך יישום React.
התקנת תלותים
npm install apollo-server graphql axios
הגדרת הסכימה
צור קובץ בשם schema.js
:
const { gql } = require('apollo-server');
const typeDefs = gql`
type User {
id: ID!
name: String
email: String // Ensure this matches exactly with the frontend query
}
type Query {
user(id: ID!): User
}
`;
module.exports = typeDefs;
סכימה זו מגדירה סוג User
ושאילתת user
שמביאה משתמש לפי מזהה.
יישום רזולברים
צור קובץ בשם resolvers.js
:
const resolvers = {
Query: {
user: async (_, { id }) => {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const user = await response.json();
return {
id: user.id,
name: user.name,
email: user.email, // Return email instead of profilePicture
};
} catch (error) {
throw new Error(`Failed to fetch user: ${error.message}`);
}
},
},
};
module.exports = resolvers;
הרזולר של שאילתת user
מביא נתונים מ-REST API ומחזיר רק את השדות הנדרשים.
נשתמש ב-https://jsonplaceholder.typicode.com/ עבור ה-REST API המזויף שלנו.
הגדרת השרת
צור קובץ server.js
:
const { ApolloServer } = require('apollo-server');
const typeDefs = require('./schema');
const resolvers = require('./resolvers');
const server = new ApolloServer({
typeDefs,
resolvers,
});
server.listen({ port: 4000 }).then(({ url }) => {
console.log(`GraphQL Server ready at ${url}`);
});
הפעל את השרת:
node server.js
שרת ה-GraphQL שלך פעיל ב-http://localhost:4000/graphql, ואם תבצע שאילתה לשרת שלך, זה יוביל אותך לדף הזה.
שילוב עם יישום ה-React
כעת נשנה את יישום ה-React להשתמש ב-GraphQL API.
התקנת Apollo Client
npm install @apollo/client graphql
הגדרת Apollo Client
import { ApolloClient, InMemoryCache } from '@apollo/client';
const client = new ApolloClient({
uri: 'http://localhost:4000',
cache: new InMemoryCache(),
});
כתיבת השאילתת GraphQL
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
כעת, שלב את קטעי הקוד שלמעלה עם אפליקציית ה-React שלך. הנה אפליקציית React פשוטה למטה, המאפשרת למשתמש לבחור את ה-userId ולהציג את המידע:
import { useState } from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider, gql, useQuery } from '@apollo/client';
import './App.css'; // Link to the updated CSS
const client = new ApolloClient({
uri: 'http://localhost:4000', // Ensure this is the correct URL for your GraphQL server
cache: new InMemoryCache(),
});
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
const User = ({ userId }) => {
const { loading, error, data } = useQuery(GET_USER, {
variables: { id: userId },
});
if (loading) return <p>Loading</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div className="user-container">
<h2>{data.user.name}</h2>
<p>Email: {data.user.email}</p>
</div>
);
};
const App = () => {
const [selectedUserId, setSelectedUserId] = useState("1");
return (
<ApolloProvider client={client}>
<div className="app-container">
<h1 className="title">GraphQL User Lookup</h1>
<div className="dropdown-container">
<label htmlFor="userSelect">Select User ID:</label>
<select
id="userSelect"
value={selectedUserId}
onChange={(e) => setSelectedUserId(e.target.value)}
>
{Array.from({ length: 10 }, (_, index) => (
<option key={index + 1} value={index + 1}>
{index + 1}
</option>
))}
</select>
</div>
<User userId={selectedUserId} />
</div>
</ApolloProvider>
);
};
export default App;
תוצאה
תראו פרטי משתמש פשוטים כמו זה: [קישור ל-Github].
עובדים עם מספר נקודות קצה מרובות
דמיינו סצנריו בו עליכם לקבל את הפוסטים של משתמש מסוים, יחד עם התגובות האישיות על כל פוסט. במקום לבצע שלוש בקשות נפרדות ל- API מאפליקציית React שלך ולהתמודד עם נתונים מיותרים, תוכלו לייעל את התהליך עם GraphQL. על ידי הגדרת סכימה ויצירת שאילתת GraphQL, תוכלו לבקש רק את הנתונים המדויקים שנדרשים לממשק המשתמש שלך, וזהו בקשה יעילה בכל אחת.
אנו צריכים לאחזר נתוני משתמש, את הפוסטים שלהם, ואת התגובות לכל פוסט מנקודות הקצה השונות. נשתמש ב- fetch כדי לאסוף נתונים מנקודות הקצה המרובות ולהחזיר אותם דרך GraphQL.
עדכון שוחחנים
const fetch = require('node-fetch');
const resolvers = {
Query: {
user: async (_, { id }) => {
try {
// fetch user
const userResponse = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const user = await userResponse.json();
// fetch posts for a user
const postsResponse = await fetch(`https://jsonplaceholder.typicode.com/posts?userId=${id}`);
const posts = await postsResponse.json();
// fetch comments for a post
const postsWithComments = await Promise.all(
posts.map(async (post) => {
const commentsResponse = await fetch(`https://jsonplaceholder.typicode.com/comments?postId=${post.id}`);
const comments = await commentsResponse.json();
return { post, comments };
})
);
return {
id: user.id,
name: user.name,
email: user.email,
posts: postsWithComments,
};
} catch (error) {
throw new Error(`Failed to fetch user data: ${error.message}`);
}
},
},
};
module.exports = resolvers;
עדכון סכימת GraphQL
const { gql } = require('apollo-server');
const typeDefs = gql`
type Comment {
id: ID!
name: String
email: String
body: String
}
type Post {
id: ID!
title: String
body: String
comments: [Comment]
}
type User {
id: ID!
name: String
email: String
posts: [Post]
}
type Query {
user(id: ID!): User
}
`;
module.exports = typeDefs;
הגדרת השרת ב־ server.js
נשארת זהה. לאחר שנעדכן את קוד ה-React.js, נקבל את הפלט הבא:
תוצאה
תראו משתמש מפורט כזה: [קישור ל-Github].
יתרונות של הגישה הזו
שילוב GraphQL לאפליקציית React שלך מספק מספר יתרונות:
הסרת פרטים מיותרים
תכונה מרכזית של GraphQL היא שהוא מבצע רק את מה שביקשת. השרת מחזיר רק את השדות שביקשת ווודא שכמות הנתונים שמועברת דרך הרשת נמוכה על ידי שירות רק את מה שהשאילתה דורשת, וכך משפר את הביצועים.
פשוט את קוד הקדמה
GraphQL מאפשר לך לקבל את המידע הנדרש בשאילתא אחת, ללא קשר למקורו. באופן פנימי, זה יכול לבצע 3 קריאות API כדי לקבל את המידע. זה מסייע לפשט את הקוד בחזית שלך כי עכשיו אינך צריך לתאם בקשות אסינכרוניות שונות ולשלב את התוצאות שלהן.
שיפור חוויית המפתחים
טיפוס חזק ואינטrospection של סכימות מציעים כלי עבודה טובים יותר ובדיקת שגיאות מאשר ביישום API המסורתי. יתרה מכך, ישנם סביבות אינטראקטיביות שבהן מפתחים יכולים לבנות ולבדוק שאילתות, כולל GraphiQL או Apollo Explorer.
התמודדות עם מורכבויות ואתגרים
גישה זו יש לה כמה יתרונות אך גם מציגה כמה אתגרים שצריך לנהל.
שכבת Backend נוספת
הקדמת שרת GraphQL יוצרת שכבה נוספת במבנה ה-backend שלך, ואם לא מנוהלת כראוי, היא הופכת לנקודת כישלון בודדת.
פתרון
שימו לב לטיפול בשגיאות ומעקב. כלים של קונטיינריזציה ותיאום כמו Docker ו-Kubernetes יכולים לעזור לנהל את הסקלאביליות והאמינות.
עומס פוטנציאלי על הביצועים
שרת GraphQL עשוי לבצע מספר קריאות REST API כדי לפתור שאילתא אחת, מה שיכול להוביל להשהיה ועומס על המערכת.
פתרון
שמור את התוצאות במטמון כדי להימנע מביצוע מספר קריאות ל-API. כמה כלים, כמו DataLoader, יכולים לנהל את תהליך האיסוף והמטמון של הבקשות.
סיכום
"הפשטות היא הגיבורה האולטימטיבית" – ליאונרדו דה וינצי
שילוב של GraphQL באפליקציית React שלך הוא יותר מאשר אופטימיזציה ביצועים – זה צעד אסטרטגי לבניית אפליקציות נתמכות יותר, גמישות ויעילות. על ידי טיפול באריכיטקטורת הנתונים ופשוטה, אתה לא רק משפר את חוויית המשתמש אלא גם מעצים את צוות הפיתוח שלך עם כלים ושיטות יותר טובים.
למרות שהזנה של שכבת GraphQL מתגלה עם סט קשיים משלה, היתרונות גוברים על המורכבויות לעיתים קרובות. על ידי תכנון זהיר של ההטמעה שלך, אופטימיזציה של הפתרונות שלך, ואבטחת הנקודות הקצה שלך, אתה יכול להפחית את החסרונות הפוטנציאליים. ומעבר לכך, הגמישות שמציע ה-GraphQL עשויה לשמור על יכולת האפליקציה שלך להתפשט ולצמוח.
לקבל את GraphQL לא אומר לוותר על ה-REST APIs הקיימים שלך. במקום זאת, זה מאפשר לך לנצל את נקודות החוזק שלהם תוך ספק שכבת גישה לנתונים יעילה וגמישה יותר לאפליקציות הקליינט שלך. הגישה ההיברידית זו משלבת את האמינות של REST עם אגיליות של GraphQL, ונותנת לך את הטוב משני העולמות.
אם אתה מוכן להעביר את אפליקציית React שלך לרמה הבאה, שקול לשלב את GraphQL באסטרטגיית השאיבת נתונים שלך. המסע עשוי להציג אתגרים, אך התגמולים – תהליך פיתוח חלק יותר, מפתחים מרוצים, ומשתמשים מרוצים – עשויים להפוך את זה למאמץ ששווה.
הקוד המלא זמין
אתה יכול למצוא את הקוד המלא ליישום זה במאגר ה-GitHub שלי.
Source:
https://dzone.com/articles/enhancing-react-applications-with-graphql-over-rest-apis