בניית ממשק API עם מסגרת Java Spark

1. הקדמה

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

זו בחירה טובה אם אתה רוצה לקבל Node.js כמו ניסיון בעת ​​פיתוח ממשק API אינטרנטי או מיקרו-שירותים בג'אווה. באמצעות Spark, תוכל לקבל REST API מוכן לשרת JSON בפחות מעשר שורות קוד.

נתחיל במהירות עם דוגמה של "שלום עולם", ואחריה ממשק API פשוט של REST.

2. תלות Maven

2.1. מסגרת ניצוצות

כלול את תלות Maven הבאה שלך pom.xml:

 com.sparkjava ניצוץ ליבת 2.5.4 

תוכל למצוא את הגרסה האחרונה של Spark ב- Maven Central.

2.2. ספריית Gson

במקומות שונים בדוגמה נשתמש בספריית Gson לצורך פעולות JSON. כדי לכלול את Gson בפרויקט שלך, כלול תלות זו בפרויקט שלך pom.xml:

 com.google.code.gson gson 2.8.0 

תוכל למצוא את הגרסה האחרונה של Gson ב- Maven Central.

3. תחילת העבודה עם Spark Framework

בואו נסתכל על אבני הבניין הבסיסיות של יישום Spark ונדגים שירות אינטרנט מהיר.

3.1. מסלולים

שירותי אינטרנט ב- Spark Java בנויים על מסלולים ומטפליהם. מסלולים הם מרכיבים חיוניים בספארק. לפי התיעוד, כל מסלול מורכב משלושה חלקים פשוטים - א פועל, א נָתִיב, ו התקשר חזרה.

  1. ה פועל היא שיטה המתאימה לשיטת HTTP. שיטות הפועל כוללות: קבל, פרסם, שים, מחק, ראש, עקוב, התחבר, ו אפשרויות
  2. ה נָתִיב (נקרא גם דפוס מסלול) קובע לאילו URI (ים) על המסלול להקשיב ולתת מענה
  3. ה התקשר חזרה היא פונקציית מטפל המופעלת עבור פועל ונתיב נתון על מנת ליצור ולהחזיר תגובה לבקשת ה- HTTP המתאימה. התקשרות חוזרת לוקחת אובייקט בקשה ואובייקט תגובה כטיעונים

כאן אנו מראים את המבנה הבסיסי עבור מסלול המשתמש ב- לקבל פועל:

קבל ("/ your-route-path /", (בקשה, תגובה) -> {// קוד ההתקשרות שלך});

3.2. ממשק ה- API של Hello World

בואו ניצור שירות אינטרנט פשוט שיש בו שני מסלולים לבקשות GET ומחזיר הודעות "שלום" בתגובה. מסלולים אלה משתמשים ב לקבל שיטה, שהיא ייבוא ​​סטטי מהמחלקה ניצוץ. ניצוץ:

יבוא ניצוץ סטטי. ספארק. *; מחלקה ציבורית HelloWorldService {public static void main (String [] args) {get ("/ hello", (req, res) -> "Hello, world"); get ("/ hello /: name", (req, res) -> {return "Hello," + req.params (": name");}); }}

הטיעון הראשון ל לקבל השיטה היא הנתיב למסלול. המסלול הראשון מכיל נתיב סטטי המייצג URI יחיד בלבד ("/שלום").

נתיב המסלול השני ("/ שלום /: שם") מכיל מציין מיקום עבור "שֵׁם" פרמטר, כפי שהוא מסומן על ידי הקדמת הפרמטר עם נקודתיים (":"). מסלול זה יופעל בתגובה לבקשות GET ל- URI כגון "/ שלום / ג'ו" ו "/ שלום / מרי".

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

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

3.3. בדיקת ה- API של Hello World

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

בואו נסתכל על הבקשה והתגובה למסלול הראשון:

בַּקָשָׁה:

קבל // localhost: 4567 / שלום

תְגוּבָה:

שלום עולם

בואו לבדוק את המסלול השני, עוברים את שֵׁם פרמטר בדרכו:

בַּקָשָׁה:

GET // localhost: 4567 / hello / baeldung

תְגוּבָה:

שלום, ביילדונג

ראה כיצד מיקום הטקסט "באלדונג" ב- URI שימש להתאמת דפוס המסלול "/ שלום /: שם" - גורם להפעלת פונקציית המטפל החוזרת של המסלול השני.

4. תכנון שירות RESTful

בחלק זה נתכנן שירות אינטרנט פשוט של REST להלן מִשׁתַמֵשׁ יֵשׁוּת:

משתמש בכיתה ציבורית {מזהה מחרוזת פרטי; פרטי מחרוזת firstName; שם משפחה פרטי מחרוזת; דוא"ל מחרוזת פרטי; // בונים, גטרים וקובעים}

4.1. מסלולים

בואו לרשום את המסלולים המרכיבים את ה- API שלנו:

  • GET / משתמשים - קבל רשימה של כל המשתמשים
  • GET / משתמשים /: id - קבל משתמש עם מזהה נתון
  • POST / משתמשים /: id - הוסף משתמש
  • PUT / משתמשים /: id - ערוך משתמש מסוים
  • אפשרויות / משתמשים /: מזהה - בדוק אם משתמש קיים עם מזהה נתון
  • מחק / משתמשים /: מזהה - מחק משתמש מסוים

4.2. שירות המשתמשים

להלן ה- שירות משתמש ממשק שמכריז על פעולות ה- CRUD עבור מִשׁתַמֵשׁ יֵשׁוּת:

ממשק ציבורי UserService {public void addUser (משתמש משתמש); getUsers אוסף ציבורי (); משתמש ציבורי getUser (מזהה מחרוזת); עריכת משתמש ציבורי משתמש (משתמש משתמש) זורק את UserException; מחיקה בטלנית ציבורית (מזהה מחרוזת); user boolean userExist (מזהה מחרוזת); }

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

4.3. מבנה התגובה של JSON

להלן מבנה JSON של התגובות המשמשות בשירות REST שלנו:

{status: message: data:}

ה סטָטוּס ערך השדה יכול להיות או הַצלָחָה אוֹ שְׁגִיאָה. ה נתונים שדה יכיל את ייצוג JSON של נתוני ההחזרה, כגון a מִשׁתַמֵשׁ או אוסף של משתמשים.

כאשר אין נתונים המוחזרים, או אם סטָטוּס הוא שְׁגִיאָה, נאכלס את הוֹדָעָה שדה להעברת סיבה לטעות או לחוסר נתוני החזרה.

בואו נציג את מבנה JSON הנ"ל באמצעות מחלקת Java:

מעמד ציבורי StandardResponse {StatusResponse פרטי; הודעת מחרוזת פרטית; נתונים פרטיים של JsonElement; ציבורי StandardResponse (StatusResponse status) {// ...} StandardResponse public (StatusResponse status, String message) {// ...} StandardResponse public (StatusResponse status, JsonElement data) {// ...} // getters and setters }

איפה תגובה הוא enum מוגדר להלן:

enum ציבורי StatusResponse {SUCCESS ("הצלחה"), שגיאה ("שגיאה"); סטטוס מחרוזת פרטי; // בונים, גטרים}

5. יישום שירותים RESTful

עכשיו בואו וניישם את המסלולים והמטפלים עבור ה- REST API שלנו.

5.1. יצירת בקרים

מחלקת Java הבאה מכילה את המסלולים עבור ה- API שלנו, כולל פעלים ונתיבים ומתאר של המטפלים לכל מסלול:

class class SparkRestExample {public static void main (String [] args) {post ("/ users", (בקשה, תגובה) -> {// ...}); קבל ("/ משתמשים", (בקשה, תגובה) -> {// ...}); get ("/ users /: id", (בקשה, תגובה) -> {// ...}); put ("/ users /: id", (בקשה, תגובה) -> {// ...}); מחק ("/ users /: id", (בקשה, תגובה) -> {// ...}); אפשרויות ("/ users /: id", (בקשה, תגובה) -> {// ...}); }}

אנו נציג את היישום המלא של כל מטפל במסלולים בסעיפים המשניים הבאים.

5.2. הוסף משתמש

להלן ה- הודעה מטפל בתגובת שיטה שיוסיף א מִשׁתַמֵשׁ:

פוסט ("/ משתמשים", (בקשה, תגובה) -> {respons.type ("יישום / json"); משתמש משתמש = Gson חדש (). fromJson (request.body (), User.class); userService.addUser (משתמש); להחזיר Gson חדש () .toJson (StandardResponse חדש (StatusResponse.SUCCESS));});

הערה: בדוגמה זו, ייצוג ה- JSON של ה- מִשׁתַמֵשׁ האובייקט מועבר כגוף הגולמי של בקשת POST.

בואו לבדוק את המסלול:

בַּקָשָׁה:

POST // localhost: 4567 / משתמשים {"id": "1012", "email": "[email protected]", "firstName": "Mac", "lastName": "Mason1"}

תְגוּבָה:

{"status": "SUCCESS"}

5.3. קבל את כל המשתמשים

להלן ה- לקבל מטפל בתגובת שיטה שמחזיר את כל המשתמשים מה- שירות משתמש:

קבל ("/ משתמשים", (בקשה, תגובה) -> {respons.type ("יישום / json"); להחזיר Gson חדש (). toJson (חדש StandardResponse (StatusResponse.SUCCESS, Gson חדש () .toJsonTree (userService. getUsers ())));});

עכשיו בואו לבדוק את המסלול:

בַּקָשָׁה:

GET // localhost: 4567 / משתמשים

תְגוּבָה:

{"status": "SUCCESS", "data": [{"id": "1014", "firstName": "John", "lastName": "Miller", "email": "[דוא"ל מוגן]"} , {"id": "1012", "firstName": "Mac", "lastName": "Mason1", "email": "[דוא"ל מוגן]"}}}

5.4. קבל משתמש לפי מזהה

להלן ה- לקבל מטפל בתגובת שיטה שמחזיר א מִשׁתַמֵשׁ עם הנתון תְעוּדַת זֶהוּת:

get ("/ users /: id", (request, response) -> {response.type ("application / json"); להחזיר Gson חדש (). toJson (StandardResponse חדש (StatusResponse.SUCCESS, Gson חדש () .toJsonTree (userService.getUser (request.params (": id")))))}});

עכשיו בואו לבדוק את המסלול:

בַּקָשָׁה:

קבל // localhost: 4567 / משתמשים / 1012

תְגוּבָה:

{"status": "SUCCESS", "data": {"id": "1012", "firstName": "Mac", "lastName": "Mason1", "email": "[דוא"ל מוגן]"}}

5.5. ערוך משתמש

להלן ה- לָשִׂים מטפל בתגובת שיטה, אשר עורך את המשתמש שיש לו את תְעוּדַת זֶהוּת מסופק בתבנית המסלול:

put ("/ users /: id", (בקשה, תגובה) -> {respons.type ("יישום / json"); משתמש toEdit = Gson חדש (). fromJson (request.body (), User.class); משתמש editedUser = userService.editUser (toEdit); אם (editedUser! = Null) {להחזיר Gson חדש (). ToJson (StandardResponse חדש (StatusResponse.SUCCESS, Gson חדש () .toJsonTree (editedUser)));} אחר {להחזיר חדש Gson (). ToJson (חדש StandardResponse (StatusResponse.ERROR, Gson חדש () .toJson ("המשתמש לא נמצא או שגיאה בעריכה")))}});

הערה: בדוגמה זו, הנתונים מועברים בגוף הגולמי של בקשת POST כאובייקט JSON ששמות המאפיינים שלו תואמים את השדות של מִשׁתַמֵשׁ אובייקט שיש לערוך.

בואו לבדוק את המסלול:

בַּקָשָׁה:

PUT // localhost: 4567 / users / 1012 {"lastName": "Mason"}

תְגוּבָה:

{"status": "SUCCESS", "data": {"id": "1012", "firstName": "Mac", "lastName": "Mason", "email": "[דוא"ל מוגן]"}}

5.6. מחק משתמש

להלן ה- לִמְחוֹק מטפל בתגובת שיטה, אשר ימחק את מִשׁתַמֵשׁ עם הנתון תְעוּדַת זֶהוּת:

מחק ("/ משתמשים /: id", (בקשה, תגובה) -> {respons.type ("יישום / json"); userService.deleteUser (request.params (": id")); להחזיר Gson חדש (). toJson (חדש StandardResponse (StatusResponse.SUCCESS, "המשתמש נמחק"))}};

עכשיו, בואו נבדוק את המסלול:

בַּקָשָׁה:

מחק // localhost: 4567 / משתמשים / 1012

תְגוּבָה:

{"status": "SUCCESS", "message": "המשתמש נמחק"}

5.7. בדוק אם קיים משתמש

ה אפשרויות שיטה היא בחירה טובה לבדיקה מותנית. להלן ה- אפשרויות מטפל בתגובת שיטה אשר יבדוק האם א מִשׁתַמֵשׁ עם הנתון תְעוּדַת זֶהוּת קיים:

אפשרויות ("/ משתמשים /: id", (בקשה, תגובה) -> {respons.type ("יישום / json"); להחזיר Gson חדש (). toJson (חדש StandardResponse (StatusResponse.SUCCESS, (userService.userExist) .params (": id")))? "משתמש קיים": "משתמש לא קיים"));});

עכשיו בואו לבדוק את המסלול:

בַּקָשָׁה:

אפשרויות // localhost: 4567 / משתמשים / 1012

תְגוּבָה:

{"status": "SUCCESS", "message": "המשתמש קיים"}

6. מסקנה

במאמר זה, היה לנו מבוא מהיר למסגרת Spark לפיתוח מהיר של אתרים.

מסגרת זו מקודמת בעיקר ליצירת מיקרו-שירותים בג'אווה. Node.js מפתחים בעלי ידע בג'אווה שרוצים למנף ספריות הבנויות על ספריות JVM צריכים להרגיש בבית באמצעות מסגרת זו.

וכמו תמיד, תוכלו למצוא את כל המקורות להדרכה זו בפרויקט Github.