HTTP PUT לעומת HTTP PATCH ב- REST API

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

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

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

2. מתי להשתמש בפוט ומתי תיקון?

נתחיל בהצהרה פשוטה ומעט פשוטה.

כאשר לקוח צריך להחליף משאב קיים לחלוטין, הוא יכול להשתמש ב- PUT. כאשר הם מבצעים עדכון חלקי, הם יכולים להשתמש ב- HTTP PATCH.

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

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

3. יישום לוגיקה של PUT ו- PATCH

נניח שאנחנו רוצים ליישם את ה- REST API לעדכון a HeavyResource עם מספר שדות:

מחלקה ציבורית HeavyResource {מזהה שלם פרטי; שם מחרוזת פרטי; כתובת מחרוזת פרטית; // ...

ראשית, עלינו ליצור את נקודת הקצה המטפלת בעדכון מלא של המשאב באמצעות PUT:

@PutMapping ("/ heavyyresource / {id}") ResponseEntity ציבורי saveResource (@RequestBody HeavyResource heavyResource, @PathVariable ("id") מזהה מחרוזת) {heavyResourceRepository.save (heavyResource, id); החזר ResponseEntity.ok ("משאב נשמר"); }

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

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

אנחנו יכולים ליצור HeavyResourceAddressOnly DTO לייצג עדכון חלקי של שדה הכתובת:

כיתה ציבורית HeavyResourceAddressOnly {מזהה שלם פרטי פרטי; כתובת מחרוזת פרטית; // ...}

לאחר מכן נוכל למנף את שיטת PATCH כדי לשלוח עדכון חלקי:

@PatchMapping ("/ heavyyresource / {id}") ResponseEntity ציבורי partialUpdateName (@RequestBody HeavyResourceAddressOnly partialUpdate, @PathVariable ("id") מזהה מחרוזת) {heavyResourceRepository.save (partialUpdate, id); החזר ResponseEntity.ok ("כתובת המשאב עודכנה"); }

עם ה- DTO הגרעיני יותר הזה, אנו יכולים לשלוח את השדה שעלינו לעדכן בלבד - ללא התקורה לשליחת שלם HeavyResource.

אם יש לנו מספר גדול של פעולות העדכון החלקיות הללו, אנו יכולים גם לדלג על יצירת DTO מותאם אישית לכל יציאה - ולהשתמש רק במפה:

@RequestMapping (value = "/ heavyyresource / {id}", method = RequestMethod.PATCH, consumes = MediaType.APPLICATION_JSON_VALUE) Public ResponseEntity partialUpdateGeneric (@RequestBody עדכוני מפה, @PathVariable ("id") מזהה מחרוזת) {heavyResourceReport עדכונים, מזהה); החזר ResponseEntity.ok ("המשאב עודכן"); }

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

4. בדיקת PUT ו- PATCH

לבסוף, בואו נכתוב בדיקות לשתי שיטות ה- HTTP. ראשית, אנו רוצים לבדוק את עדכון המשאב המלא באמצעות שיטת PUT:

mockMvc.perform (put ("/ heavyyresource / 1") .contentType (MediaType.APPLICATION_JSON_VALUE) .content (objectMapper.writeValueAsString (HeavyResource חדש (1, "טום", "ג'קסון", 12, "רחוב גן עדן")))) .andExpect (status (). isOk ());

ביצוע עדכון חלקי מושג בשיטת PATCH:

mockMvc.perform (תיקון ("/ heavyyrecource / 1") .contentType (MediaType.APPLICATION_JSON_VALUE) .content (objectMapper.writeValueAsString (HeavyResourceAddressOnly חדש (1, "השדרה החמישית")))). ו- Expect (מצב ()). );

אנו יכולים גם לכתוב מבחן לגישה כללית יותר:

עדכוני HashMap = HashMap חדש (); updates.put ("כתובת", "השדרה החמישית"); mockMvc.perform (patch ("/ heavyyresource / 1") .contentType (MediaType.APPLICATION_JSON_VALUE) .content (objectMapper.writeValueAsString (updates))) .andExpect (status (). isOk ()); 

5. טיפול בבקשות חלקיות עם ריק ערכים

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

נניח שלקוח זה ישלח את הבקשה הבאה:

{"id": 1, "address": null}

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

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

6. מסקנה

במדריך מהיר זה התמקדנו בהבנת ההבדלים בין שיטות HTTP PATCH ו- PUT.

יישמנו בקר Spring REST פשוט לעדכון שיטת משאבים באמצעות PUT ועדכון חלקי באמצעות PATCH.

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