PUT vs. POST στο REST

Σύμφωνα με την προδιαγραφή HTTP/1.1:

Η μέθοδος POST χρησιμοποιείται για να ζητηθεί από τον διακομιστή προέλευσης να αποδεχθεί την οντότητα που περικλείεται στην αίτηση ως νέο υποκείμενο του πόρου που προσδιορίζεται από το Request-URI στη Request-Line.

Με άλλα λόγια, η μέθοδος POST χρησιμοποιείται για τη δημιουργία.

Η μέθοδος PUT ζητά να αποθηκευτεί η οντότητα που περικλείεται κάτω από το παρεχόμενο Request-URI. Εάν το Request-URI αναφέρεται σε έναν ήδη υπάρχοντα πόρο, η περιεχόμενη οντότητα ΘΑ ΠΡΕΠΕΙ να θεωρηθεί ως τροποποιημένη έκδοση εκείνης που βρίσκεται στον αρχικό διακομιστή. Εάν το Request-URI δεν παραπέμπει σε έναν υπάρχοντα πόρο και το εν λόγω URI μπορεί να οριστεί ως νέος πόρος από τον αιτούντα πράκτορα χρήστη, ο διακομιστής προέλευσης μπορεί να δημιουργήσει τον πόρο με αυτό το URI,

Δηλαδή, το PUT χρησιμοποιείται για τη δημιουργία ή την ενημέρωση.

Οπότε, ποιο από τα δύο πρέπει να χρησιμοποιείται για τη δημιουργία ενός πόρου; Ή πρέπει να υποστηρίζονται και τα δύο;

Λύση

Συνολικά:

Τόσο η PUT όσο και η POST μπορούν να χρησιμοποιηθούν για τη δημιουργία.

Πρέπει να ρωτήσετε "σε τι εκτελείτε την ενέργεια; " για να διακρίνετε τι πρέπει να χρησιμοποιήσετε. Ας υποθέσουμε ότι σχεδιάζετε ένα API για την υποβολή ερωτήσεων. Αν θέλετε να χρησιμοποιήσετε POST τότε θα το κάνετε σε μια λίστα ερωτήσεων. Αν θέλετε να χρησιμοποιήσετε PUT τότε θα το κάνετε σε μια συγκεκριμένη ερώτηση.

Μεγάλη και οι δύο μπορούν να χρησιμοποιηθούν, οπότε ποια θα πρέπει να χρησιμοποιήσω στον RESTful σχεδιασμό μου:

Δεν χρειάζεται να υποστηρίζετε τόσο το PUT όσο και το POST.

Ποιο από τα δύο θα χρησιμοποιηθεί εξαρτάται από εσάς. Αλλά απλά θυμηθείτε να χρησιμοποιείτε το σωστό ανάλογα με το αντικείμενο στο οποίο αναφέρεστε στην αίτηση.

Ορισμένες σκέψεις:

  • Ονομάζετε ρητά τα αντικείμενα URL που δημιουργείτε ή αφήνετε τον διακομιστή να αποφασίσει; Εάν τα ονομάζετε, τότε χρησιμοποιήστε το PUT. Εάν αφήσετε τον διακομιστή να αποφασίσει τότε χρησιμοποιήστε POST.
  • Το PUT είναι idempotent, οπότε αν κάνετε PUT ένα αντικείμενο δύο φορές, δεν έχει κανένα αποτέλεσμα. Αυτή είναι μια ωραία ιδιότητα, οπότε θα χρησιμοποιούσα το PUT όταν είναι δυνατόν.
  • Μπορείτε να ενημερώσετε ή να δημιουργήσετε έναν πόρο με PUT με την ίδια διεύθυνση URL αντικειμένου
  • Με το POST μπορείτε να έχετε 2 αιτήσεις που έρχονται ταυτόχρονα και κάνουν τροποποιήσεις σε μια διεύθυνση URL, και μπορεί να ενημερώσουν διαφορετικά μέρη του αντικειμένου.

Ένα παράδειγμα:

Έγραψα τα ακόλουθα ως μέρος μιας άλλης απάντησης στο SO σχετικά με αυτό:

POST: &gt, Χρησιμοποιείται για την τροποποίηση και ενημέρωση ενός πόρου &gt, POST /questions/ HTTP/1.1 Host: www.example.com/ &gt, Σημειώστε ότι τα ακόλουθα αποτελούν σφάλμα: &gt, POST /questions/ HTTP/1.1 Host: www.example.com/ &gt, &gt, Εάν η διεύθυνση URL δεν έχει ακόμη δημιουργηθεί, μπορείτε δεν θα πρέπει να χρησιμοποιήσετε POST για να τη δημιουργήσετε ενώ προσδιορίζετε το όνομα. Αυτό θα πρέπει οδηγήσει σε σφάλμα 'resource not found' επειδή το δεν υπάρχει ακόμα. Θα πρέπει να PUT το στον διακομιστή πρώτα. &gt, &gt, Θα μπορούσατε όμως να κάνετε κάτι τέτοιο αυτό για να δημιουργήσετε έναν πόρο χρησιμοποιώντας POST: &gt, &gt, POST /questions HTTP/1.1 Host: www.example.com/ &gt, Σημειώστε ότι σε αυτή την περίπτωση ο πόρος όνομα δεν καθορίζεται, τα νέα αντικείμενα διαδρομή URL θα σας επιστραφεί. &gt, PUT: &gt, Χρησιμοποιείται για τη δημιουργία ενός πόρου, ή να τον αντικαταστήσει. Ενώ καθορίζετε το πόρων νέα διεύθυνση URL. &gt, Για έναν νέο πόρο: &gt, PUT /questions/ HTTP/1.1 Host: www.example.com/ &gt, Για να αντικαταστήσετε έναν υπάρχοντα πόρο: &gt, PUT /questions/ HTTP/1.1 Host: www.example.com/ &gt,

Σχόλια (41)

Χρησιμοποιήστε POST για να δημιουργήσετε και PUT για να ενημερώσετε. Έτσι το κάνει η Ruby on Rails, τουλάχιστον.

PUT    /items/1      #=> update
POST   /items        #=> create
Σχόλια (8)

Το REST είναι μια πολύ υψηλού επιπέδου έννοια. Στην πραγματικότητα, δεν αναφέρει καν το HTTP!

Αν έχετε αμφιβολίες για το πώς να υλοποιήσετε το REST σε HTTP, μπορείτε πάντα να ρίξετε μια ματιά στην προδιαγραφή [Atom Publication Protocol (AtomPub)][1]. Το AtomPub είναι ένα πρότυπο για τη συγγραφή RESTful webservices με HTTP που αναπτύχθηκε από πολλούς φωστήρες του HTTP και του REST, με κάποια συμβολή από τον Roy Fielding, τον εφευρέτη του REST και (συν)εφευρέτη του ίδιου του HTTP.

Στην πραγματικότητα, ίσως να μπορείτε να χρησιμοποιήσετε το AtomPub απευθείας. Αν και προήλθε από την κοινότητα των ιστολογίων, δεν περιορίζεται σε καμία περίπτωση στο ιστολόγιο: είναι ένα γενικό πρωτόκολλο για την αλληλεπίδραση με REST με αυθαίρετες (εμφωλευμένες) συλλογές αυθαίρετων πόρων μέσω HTTP. Αν μπορείτε να αναπαραστήσετε την εφαρμογή σας ως μια φωλιασμένη συλλογή πόρων, τότε μπορείτε απλά να χρησιμοποιήσετε το AtomPub και να μην ανησυχείτε για το αν θα χρησιμοποιήσετε PUT ή POST, τι κωδικούς κατάστασης HTTP θα επιστρέψετε και όλες αυτές τις λεπτομέρειες.

Αυτό έχει να πει το AtomPub για τη δημιουργία πόρων (ενότητα 9.2):

Για να προσθέσουν μέλη σε μια Συλλογή, οι πελάτες στέλνουν αιτήσεις POST στο URI της Συλλογής.

Σχόλια (9)