תחילת העבודה עם GraphQL ו- Spring Boot

1. הקדמה

GraphQL הוא מושג חדש יחסית מפייסבוק המחויב כחלופה ל- REST עבור ממשקי API של רשת.

מאמר זה ייתן מבוא להגדרת שרת GraphQL באמצעות Spring Boot כך שניתן יהיה להוסיף אותו ליישומים קיימים או להשתמש בו ביישומים חדשים.

2. מה זה GraphQL?

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

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

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

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

לדוגמה, בלוג עשוי לאפשר את השאילתה הבאה:

שאילתה {recentPosts (ספירה: 10, קיזוז: 0) {מחבר קטגוריית כותרת מזהה {שם תמונה ממוזערת}}}

שאילתה זו תעשה:

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

ב- API של REST מסורתי, זה צריך 11 בקשות - אחת עבור ההודעות ו -10 עבור המחברים - או צריך לכלול את פרטי המחבר בפרטי הפוסט.

2.1. תוכניות GraphQL

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

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

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

הקלד Post {id: ID! כותרת: מחרוזת! טקסט: מחרוזת! קטגוריה: מחבר מחרוזת: מחבר! } הקלד מחבר {id: ID! שם: מחרוזת! תמונה ממוזערת: הודעות מחרוזת: [פוסט]! } # שאילתת השורש עבור שאילתת סוג היישום {recentPosts (ספירה: Int, קיזוז: Int): [פוסט]! } # מוטציה השורשית עבור סוג היישום מוטציה {writePost (כותרת: מחרוזת !, טקסט: מחרוזת !, קטגוריה: מחרוזת): פוסט! }

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

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

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

3. היכרות עם GraphQL Spring Boot Starter

Spring Boot GraphQL Starter מציע דרך נהדרת להפעיל שרת GraphQL תוך זמן קצר מאוד. בשילוב עם ספריית כלי ה- Java של GraphQL, עלינו לכתוב רק את הקוד הדרוש לשירותנו.

3.1. הגדרת השירות

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

 com.graphql-java graphql-spring-boot-starter 5.0.2 com.graphql-java graphql-java-tools 5.2.4 

Spring Boot יבחר באופן אוטומטי את אלה ויגדיר את המטפלים המתאימים לעבודה אוטומטית.

כברירת מחדל, הדבר יחשוף את שירות GraphQL ב- / graphql נקודת קצה של היישום שלנו ונקבל בקשות POST המכילות את עומס התשלום של GraphQL. ניתן להתאים את נקודת הקצה הזו שלנו application.properties הגש במידת הצורך.

3.2. כתיבת הסכימה

ספריית הכלים של GraphQL עובדת על ידי עיבוד קבצי GraphQL Schema לבניית המבנה הנכון ואז מחווטת שעועית מיוחדת למבנה זה. המתנע של Spring Boot GraphQL מוצא אוטומטית קבצי סכימה אלה.

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

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

3.3. פותר שאילתות שורש

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

הדרישות היחידות הן שהשעועית תיישם GraphQLQueryResolver וכי לכל שדה בשאילתת השורש מהתכנית יש שיטה באחד מהמחלקות האלה עם אותו שם.

שאילתת מחלקה ציבורית מיישמת GraphQLQueryResolver {פרטית PostDao postDao; רשימה ציבורית getRecentPosts (int count, int offset) {return postsDao.getRecentPosts (count, offset); }}

שמות השיטה חייבים להיות אחד מהבאים, לפי סדר זה:

  1. is - רק אם השדה הוא מסוג בוליאני
  2. לקבל

השיטה חייבת לכלול פרמטרים התואמים לכל פרמטרים בסכימת GraphQL, והיא עשויה לקחת פרמטר סופי מסוג זה DataFetchingEnvironment.

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

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

3.4. שימוש בשעועית לייצוג סוגים

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

שדות בתוך שעועית הג'אווה ימופו ישירות על שדות בתגובת GraphQL בהתבסס על שם השדה.

מחלקה ציבורית הודעה {מזהה מחרוזת פרטי; כותרת מחרוזת פרטית; קטגוריית מחרוזת פרטית; פרטי מחרוזת מחרוזת; }

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

למשל, השדה authorId כאן אינו תואם לשום דבר בסכמה שהגדרנו קודם לכן, אך הוא יהיה זמין לשימוש לשלב הבא.

3.5. פתרוני שדה לערכים מורכבים

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

פותר השדה הוא כל שעועית בהקשר האביבי בשם זהה שעועית הנתונים, עם הסיומת פותר, וזה מיישם את GraphQLResolver מִמְשָׁק. השיטות בשעועית פותר השדה עוקבות אחר כל אותם הכללים כמו על שעועית הנתונים, אך גם מספקות את שעועית הנתונים עצמה כפרמטר ראשון.

אם לפותר שדה ולשעועית הנתונים יש שיטות לאותו שדה GraphQL אז לפותר השדה תהיה עדיפות.

מחלקה ציבורית PostResolver מיישמת את GraphQLResolver {authorDao הפרטי authorDao; מחבר ציבורי getAuthor (פרסם פוסט) {החזיר authorDao.getAuthorById (post.getAuthorId ()); }}

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

חשוב לציין, אם הלקוח לא מבקש שדה, שרת GraphQL לעולם לא יעשה את העבודה כדי לאחזר אותו. משמעות הדבר היא שאם לקוח מאחזר פוסט ולא מבקש את המחבר, אז getAuthor () השיטה לעיל לעולם לא תבוצע, וקריאת ה- DAO לעולם לא תתבצע.

3.6. ערכים בטלים

לסכימת GraphQL יש את הרעיון שחלק מהסוגים אינם ניתנים לביטול ואחרים אינם.

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

זה מאוד שימושי מכיוון שמשמעותו היא שקוד ה- Java שלנו ברור יותר זהה לסכמת GraphQL מהגדרות השיטה.

3.7. מוטציות

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

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

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

מוטציות מוגדרות בקוד Java באמצעות שיעורים המיישמים GraphQLMutationResolver במקום GraphQLQueryResolver.

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

מוטציה בכיתה ציבורית מיישמת את GraphQLMutationResolver {פרטי PostDao postDao; Public PostPost (כותרת מחרוזת, טקסט מחרוזת, קטגוריית מחרוזות) {return postDao.savePost (כותרת, טקסט, קטגוריה); }}

4. היכרות עם GraphiQL

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

ניתן גם לכלול את הגרסה מבוססת האינטרנט של GraphiQL ביישום שלנו באופן אוטומטי, על ידי הוספת התלות של Spring Boot Starter של GraphiQL:

 com.graphql-java graphiql-spring-boot-starter 5.0.2 

זה יעבוד רק אם אנו מארחים את ה- API של GraphQL שלנו בנקודת הקצה המוגדרת כברירת מחדל / graphql אם כי, כך יישום העצמאי יהיה צורך אם זה לא המקרה.

5. סיכום

GraphQL היא טכנולוגיה חדשה ומלהיבה שיכולה לחולל מהפכה באופן שבו פותחים ממשקי API של רשת.

השילוב של Spring Boot GraphQL Starter וספריות כלי Java Java מקלים על הוספת טכנולוגיה זו לכל יישומי Spring Boot חדשים או קיימים.

ניתן למצוא קטעי קוד ב- GitHub.