מבוא ל- GraphQL

1. סקירה כללית

GraphQL היא שפת שאילתות, שנוצרה על ידי פייסבוק במטרה לבנות יישומי לקוח על בסיס תחביר אינטואיטיבי וגמיש, לתיאור דרישות הנתונים שלהם ואינטראקציות.

אחד האתגרים העיקריים בשיחות REST מסורתיות הוא חוסר היכולת של הלקוח לבקש סט נתונים מותאם אישית (מוגבל או מורחב). ברוב המקרים, ברגע שהלקוח מבקש מידע מהשרת, הוא מקבל את כל השדות או את אף אחד מהם.

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

בעת בניית שרת GraphQL, יש צורך רק בכתובת אתר אחת לכל האיסוף וההשתנות של הנתונים. לפיכך, לקוח יכול לבקש סט נתונים על ידי שליחת מחרוזת שאילתה, המתארת ​​את מבוקשו, לשרת.

2. שמות בסיסיים של GraphQL

בואו נסתכל על המינוח הבסיסי של GraphQL.

  • שאילתא: היא פעולה לקריאה בלבד המתבקשת לשרת GraphQL
  • מוּטָצִיָה: היא פעולת קריאה-כתיבה המתבקשת לשרת GraphQL
  • פותר: ב- GraphQL, ה- פותר אחראי על מיפוי הפעולה והקוד הפועל על גבי ה- backend האחראי לטיפול בבקשה. זה מקביל ל- MVC backend ביישום RESTFul
  • סוּג: א סוּג מגדיר את צורת נתוני התגובה שניתן להחזיר משרת GraphQL, כולל שדות שהם קצוות לאחרים סוגים
  • קֶלֶט: כמו סוּג, אך מגדיר את צורת נתוני הקלט הנשלחים לשרת GraphQL
  • סקלר: הוא פרימיטיבי סוּג, כגון א חוּט, Int, בוליאני, לָצוּף, וכו
  • מִמְשָׁק: ממשק יאחסן את שמות השדות ואת הטיעונים שלהם, כך שאובייקטים של GraphQL יכולים לרשת ממנו, ולהבטיח את השימוש בשדות ספציפיים.
  • סכֵימָה: ב- GraphQL, הסכימה מנהלת שאילתות ומוטציות, ומגדירה מה מותר לבצע בשרת GraphQL

2.1. טוען סכמה

ישנן שתי דרכים לטעינת סכימה בשרת GraphQL:

  1. באמצעות שפת הגדרת הממשק של GraphQL (IDL)
  2. באמצעות אחת משפות התכנות הנתמכות

בואו נדגים דוגמא באמצעות IDL:

הקלד משתמש {firstName: String}

כעת, דוגמה להגדרת סכימה המשתמשת בקוד Java:

GraphQLObjectType userType = newObject () .name ("User") .field (newFieldDefinition () .name ("firstName") .type (GraphQLString)) .build ();

3. שפת הגדרת ממשק

שפת הגדרת ממשק (IDL) או שפת הגדרת Schema (SDL) היא הדרך התמציתית ביותר לציין סכמת GraphQL. התחביר מוגדר היטב והוא יאומץ במפרט הרשמי של GraphQL.

לדוגמה, בואו ליצור סכימת GraphQL עבור משתמש / הודעות דוא"ל ניתן לציין כך:

schema {query: QueryType} enum Gender {MALE FEMALE} סוג משתמש {id: String! firstName: מחרוזת! lastName: מחרוזת! createdAt: DateTime! גיל: Int! @default (ערך: 0) מין: [מין]! מיילים: [דוא"ל!]! @relation (name: "Emails")} הקלד דוא"ל {id: String! דוא"ל: מחרוזת! ברירת מחדל: Int! משתמש @default (ערך: 0): משתמש @relation (שם: "דוא"ל")}

4. GraphQL-java

GraphQL-java הוא יישום המבוסס על המפרט והטמעת JavaScript. שים לב שהוא דורש לפחות Java 8 כדי לפעול כראוי.

4.1. הערות GraphQL-java

GraphQL מאפשר גם להשתמש בהערות Java כדי ליצור את הגדרת הסכימה שלה ללא כל קוד ה- boilerplate שנוצר באמצעות הגישה המסורתית של IDL.

4.2. תלות

כדי ליצור את הדוגמה שלנו, ראשית נתחיל לייבא את התלות הנדרשת המסתמכת על מודול Graphql-java-annotations:

 com.graphql-java graphql-java-annotations 3.0.3 

אנו מיישמים גם ספריית HTTP כדי להקל על ההתקנה ביישום שלנו. אנו הולכים להשתמש ב- Ratpack (אם כי ניתן ליישם אותו גם עם Vert.x, Spark, Dropwizard, Spring Boot וכו ').

בואו ונייבא גם את התלות של Ratpack:

 io.ratpack ratpack-core 1.4.6 

4.3. יישום

בואו ליצור את הדוגמה שלנו: ממשק API פשוט המספק "CRUDL" (יצירה, אחזור, עדכון, מחיקה ורשימה) למשתמשים. ראשית, בואו ניצור את שלנו מִשׁתַמֵשׁ POJO:

@GraphQLName ("משתמש") משתמש בכיתה ציבורית {@GraphQLField מזהה פרטי פרטי; @GraphQLField שם מחרוזת פרטי; דוא"ל מחרוזת פרטי @GraphQLField; // הושמטו גטרים, סטרים, בונים ושיטות עוזר}

ב- POJO זה אנו יכולים לראות את @GraphQLName ("משתמש") ביאור, כאינדיקציה כי מחלקה זו ממופה על ידי GraphQL יחד עם כל שדה עם הערות @GraphQLField.

לאחר מכן, ניצור את UserHandler מעמד. מחלקה זו יורשת מספריית מחברי ה- HTTP שנבחרה (במקרה שלנו, Ratpack) שיטת מטפל, שתנהל ותפעיל את גרפי ה- SQL פותר תכונה. לפיכך, הפניית הבקשה (מטעי מטען JSON) לפעולת השאילתה או המוטציה הנכונה:

@ Override ידית חלל ציבורית (הקשר הקשר) זורקת חריגה {context.parse (Map.class). ואז (מטען -> {Map parameters = (Map) payload.get ("parameters"); ExecutionResult executionResult = graphql. Execute (loadload) .get (SchemaUtils.QUERY) .toString (), null, זה, פרמטרים); Map result = new LinkedHashMap (); if (executionResult.getErrors (). isEmpty ()) {result.put (SchemaUtils.DATA, executionResult. getData ());} אחר {result.put (SchemaUtils.ERRORS, executionResult.getErrors ()); LOGGER.warning ("שגיאות:" + executResult.getErrors ());} context.render (json (תוצאה)); }); }

כעת, המחלקה שתתמוך בפעולות השאילתה, כלומר, UserQuery. כאמור כל השיטות שאוחזרות נתונים מהשרת ללקוח מנוהלות על ידי מחלקה זו:

@GraphQLName ("שאילתה") מחלקת ציבור UserQuery {@GraphQLField ציבור סטטי ציבורי retrieveUser (DataFetchingEnvironment env, @NotNull @GraphQLName ("id") מזהה מחרוזת) {// להחזיר משתמש} @GraphQLField רשימת רשימה סטטית ציבורית רשימת משתמשים (DataFetchingEnvironment env) { // רשימת משתמשים חוזרים}}

דומה ל UserQuery, עכשיו אנחנו יוצרים UserMutation, אשר ינהל את כל הפעולות המתכוונות לשנות נתונים מסוימים המאוחסנים בצד השרת:

@GraphQLName ("מוטציה") מחלקה ציבורית UserMutation {@ GraphQLField משתמש סטטי ציבורי createUser (DataFetchingEnvironment env, @NotNull @GraphQLName ("name") שם מחרוזת, @NotNull @GraphQLName ("דוא"ל") דוא"ל מחרוזת) {// צור משתמש מידע}}

כדאי לשים לב להערות בשניהם UserQuery ו UserMutation שיעורים: @GraphQLName ("שאילתה") ו @GraphQLName ("מוטציה"). הערות אלו משמשות להגדרת פעולות השאילתה והמוטציה בהתאמה.

כאשר שרת GraphQL-java מסוגל להריץ את פעולות השאילתה והמוטציה, אנו יכולים להשתמש בעומסי התשלום הבאים של JSON כדי לבדוק את בקשת הלקוח מול השרת:

  • לפעולה CREATE:
{"query": "מוטציה ($ name: String! $ email: String!) {createUser (name: $ name email: $ email) {id name email age}}", "parameters": {"name": " ג'ון "," דוא"ל ":" [דוא"ל מוגן] "}} 

כתגובת השרת לפעולה זו:

{"data": {"createUser": {"id": 1, "name": "John", "email": "[email protected]"}}
  • לפעולה RETRIEVE:
{"query": "query ($ id: String!) {retrieveUser (id: $ id) {name email}}", "parameters": {"id": 1}}

כתגובת השרת לפעולה זו:

{"data": {"retrieveUser": {"name": "John", "email": "[email protected]"}}}

GraphQL מספק תכונות שהלקוח יכול להתאים אישית את התגובה. לכן, בפעולת ה- RETRIEVE האחרונה ששימשה כדוגמה, במקום להחזיר את השם והדואר האלקטרוני, אנו יכולים, למשל, להחזיר רק את הדוא"ל:

{"query": "query ($ id: String!) {retrieveUser (id: $ id) {email}}", "parameters": {"id": 1}}

לכן, המידע החוזר משרת GraphQL יחזיר רק את הנתונים המבוקשים:

{"data": {"retrieveUser": {"email": "[email protected]"}}

5. מסקנה

GraphQL היא דרך קלה ודי אטרקטיבית למזער את המורכבות בין לקוח / שרת כגישה חלופית לממשקי API של REST.

כמו תמיד, הדוגמה זמינה במאגר GitHub שלנו.


$config[zx-auto] not found$config[zx-overlay] not found