IT-Swarm.Net

PUT εναντίον POST σε REST

Σύμφωνα με το πρότυπο HTTP/1.1:

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

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

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

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

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

4981
alex

Συνολικά:

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

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

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

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

Το οποίο χρησιμοποιείται παραμένει στο χέρι σας. Αλλά θυμηθείτε να χρησιμοποιήσετε το σωστό, ανάλογα με το αντικείμενο που αναφέρετε στο αίτημα.

Μερικές σκέψεις:

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

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

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

POST:

Χρησιμοποιείται για την τροποποίηση και την ενημέρωση ενός πόρου

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Σημειώστε ότι το ακόλουθο είναι ένα σφάλμα:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Εάν η διεύθυνση URL δεν έχει δημιουργηθεί ακόμη, δεν θα πρέπει να χρησιμοποιείτε το POST για να το δημιουργήσετε ενώ καθορίζετε το όνομα. Αυτό θα πρέπει να έχει ως αποτέλεσμα ένα σφάλμα 'πόρος δεν βρέθηκε' επειδή το <new_question> δεν υπάρχει ακόμα. Πρέπει πρώτα να τοποθετήσετε τον πόρο <new_question> στον διακομιστή.

Θα μπορούσατε όμως να κάνετε κάτι τέτοιο για να δημιουργήσετε πόρους χρησιμοποιώντας POST:

POST /questions HTTP/1.1
Host: www.example.com/

Σημειώστε ότι σε αυτήν την περίπτωση το όνομα του πόρου δεν έχει καθοριστεί, η διαδρομή URL των νέων αντικειμένων θα σας επιστραφεί.

ΣΗΜΕΙΩΣΗ:

Χρησιμοποιείται για τη δημιουργία ενός πόρου ή για την αντικατάστασή του. Ενώ ορίσετε τους πόρους νέα διεύθυνση URL.

Για έναν νέο πόρο:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

Για να αντικαταστήσετε μια υπάρχουσα πηγή:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/
3929
Brian R. Bondy

Μπορείτε να βρείτε ισχυρισμούς στο διαδίκτυο που λένε

Ούτε είναι σωστό.


Καλύτερα είναι να επιλέξετε μεταξύ PUT και POST με βάση την idempotence της ενέργειας.

PUT υπονοεί την τοποθέτηση ενός πόρου - αντικαθιστώντας εντελώς ό, τι είναι διαθέσιμο στη δεδομένη διεύθυνση URL με ένα διαφορετικό πράγμα. Εξ ορισμού, ένα PUT είναι idempotent. Κάντε το όσες φορές θέλετε και το αποτέλεσμα είναι το ίδιο. x=5 είναι idempotent. Μπορείτε να χρησιμοποιήσετε έναν πόρο είτε υπήρχε προηγουμένως είτε όχι (π.χ., Δημιουργία ή Ενημέρωση)!

POST ενημερώνει έναν πόρο, προσθέτει έναν βοηθητικό πόρο ή προκαλεί μια αλλαγή. Ένα POST δεν είναι idempotent, με τον τρόπο που x++ δεν είναι idempotent.


Με αυτό το επιχείρημα, το PUT είναι για τη δημιουργία όταν γνωρίζετε τη διεύθυνση URL του πράγματος που θα δημιουργήσετε. POST μπορεί να χρησιμοποιηθεί για τη δημιουργία όταν γνωρίζετε τη διεύθυνση URL του "εργοστασίου" ή του διαχειριστή για την κατηγορία των πραγμάτων που θέλετε να δημιουργήσετε.

έτσι:

POST /expense-report

ή:

PUT  /expense-report/10929
2071
Cheeso
  • POST σε μια διεύθυνση URL δημιουργεί μια πηγή παιδιού σε μια server defined URL.
  • PUT σε μια διεύθυνση URL δημιουργεί/αντικαθιστά τον πόρο στο σύνολό του στην διεύθυνση πελάτης που ορίζεται URL.
  • PATCH σε μια διεύθυνση URL pdates part του πόρου σε αυτή τη διεύθυνση URL καθορισμένη από τον πελάτη.

Η σχετική προδιαγραφή για τα PUT και POST είναι RFC 2616 §9.5ff.

POST δημιουργεί μια πηγή παιδιού, έτσι POST σε /items δημιουργεί πόρους που ζουν κάτω από τον πόρο /items. Π.χ. /items/1. Η αποστολή του ίδιου πακέτου μετά από δύο φορές θα δημιουργήσει δύο πόρους.

PUT προορίζεται για τη δημιουργία ή την αντικατάσταση ενός πόρου σε RL γνωστή από τον πελάτη.

Επομένως: PUT είναι μόνο υποψήφιος για το CREATE όπου ο πελάτης γνωρίζει ήδη τη διεύθυνση URL πριν δημιουργηθεί ο πόρος. Π.χ. /blogs/nigel/entry/when_to_use_post_vs_put καθώς ο τίτλος χρησιμοποιείται ως κλειδί πόρου

PUT αντικαθιστά τον πόρο στη γνωστή διεύθυνση url εάν υπάρχει ήδη, οπότε η αποστολή του ίδιου αιτήματος δύο φορές δεν έχει αποτέλεσμα. Με άλλα λόγια, οι κλήσεις προς το PUT είναι idempotent.

Το RFC διαβάζει ως εξής:

Η θεμελιώδης διαφορά μεταξύ των αιτήσεων POST και PUT αντικατοπτρίζεται στην διαφορετική έννοια του URI αιτήματος. Το URI σε ένα POST αίτημα προσδιορίζει τον πόρο που θα χειριστεί την εσωκλειόμενη οντότητα. Αυτός ο πόρος μπορεί να είναι μια διαδικασία αποδοχής δεδομένων, μια πύλη σε κάποιο άλλο πρωτόκολλο ή μια ξεχωριστή οντότητα που δέχεται σχολιασμούς. Αντίθετα, το URI σε ένα αίτημα PUT προσδιορίζει την οντότητα που συνοδεύει την αίτηση - ο πράκτορας χρήστη ξέρει τι προορίζεται το URI και ο διακομιστής ΔΕΝ πρέπει να επιχειρήσει να εφαρμόσει το αίτημα σε κάποιον άλλο πόρο. Εάν ο διακομιστής επιθυμεί να εφαρμοστεί το αίτημα σε διαφορετικό URI,

Σημείωση: Το PUT χρησιμοποιήθηκε ως επί το πλείστον για την ενημέρωση των πόρων (αντικαθιστώντας τα συνολικά), αλλά πρόσφατα υπάρχει κίνηση προς τη χρήση του PATCH για την ενημέρωση των υφιστάμενων πόρων, καθώς το PUT καθορίζει ότι αντικαθιστά ολόκληρο τον πόρο. RFC 5789.

Ενημέρωση 2018: Υπάρχει μια περίπτωση που μπορεί να γίνει για να αποφευχθεί το PUT. Βλέπε "REST χωρίς PUT"

Με την τεχνική "REST without PUT", η ιδέα είναι ότι οι καταναλωτές αναγκάζονται να δημοσιεύουν νέους πόρους αιτήσεων για "ανανέωση". Όπως αναφέρθηκε προηγουμένως, η αλλαγή της διεύθυνσης αλληλογραφίας ενός πελάτη είναι POST σε έναν νέο "ChangeOfAddress" πόρο, και όχι ένα PUT ενός πόρου "Πελάτη" με διαφορετική τιμή πεδίου διεύθυνσης αλληλογραφίας.

από το REST API Design - Μοντελοποίηση Πόρων από Prakash Subramaniam Thoughtworks

Αυτό αναγκάζει το API να αποφύγει προβλήματα μετάβασης στο κράτος με πολλαπλούς πελάτες που ενημερώνουν έναν μόνο πόρο και ταιριάζει καλύτερα με την προμήθεια συμβάντων και το CQRS. Όταν η εργασία γίνεται ασύγχρονα, φαίνεται ότι είναι κατάλληλη η διεξαγωγή του μετασχηματισμού και η αναμονή για την εφαρμογή του.

651
Nigel Thorne

Θα ήθελα να προσθέσω τις "ρεαλιστικές" συμβουλές μου. Χρησιμοποιήστε το PUT όταν γνωρίζετε το "id" με το οποίο μπορείτε να ανακτήσετε το αντικείμενο που αποθηκεύετε. Η χρήση του PUT δεν θα λειτουργήσει πάρα πολύ καλά εάν χρειάζεστε, ας πούμε, μια βάση δεδομένων που δημιούργησε id για να σας επιστραφεί για μελλοντικές αναζητήσεις ή ενημερώσεις.

Έτσι: Για να αποθηκεύσετε έναν υπάρχοντα χρήστη ή εκείνο στον οποίο ο πελάτης δημιουργεί το αναγνωριστικό και έχει επαληθευτεί ότι το αναγνωριστικό είναι μοναδικό:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

Διαφορετικά, χρησιμοποιήστε το POST για να δημιουργήσετε αρχικά το αντικείμενο και PUT για την ενημέρωση του αντικειμένου:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com
170
ThaDon

Το POST σημαίνει "δημιουργία νέου" όπως στο "Εδώ είναι η είσοδος για τη δημιουργία ενός χρήστη, το δημιουργήστε για μένα".

Το PUT σημαίνει "εισαγάγετε, αντικαταστήστε εάν υπάρχει ήδη" όπως στο "Εδώ είναι τα δεδομένα για τον χρήστη 5".

Μπορείτε POST στο παράδειγμα.com/users αφού δεν γνωρίζετε ακόμα τη διεύθυνση URL του χρήστη, θέλετε ο διακομιστής να το δημιουργήσει.

Μπορείτε PUT να example.com/users/id, δεδομένου ότι θέλετε να αντικαταστήσετε/δημιουργήσετε έναν συγκεκριμένο χρήστη.

Το POSTing δύο φορές με τα ίδια δεδομένα σημαίνει ότι δημιουργείτε δύο ταυτόσημους χρήστες με διαφορετικά IDs. Το PUTing δύο φορές με τα ίδια δεδομένα δημιουργεί τον χρήστη πρώτο και τον ενημερώνει στην ίδια κατάσταση τη δεύτερη φορά (χωρίς αλλαγές). Δεδομένου ότι καταλήγετε στην ίδια κατάσταση μετά από ένα PUT ανεξάρτητα από το πόσες φορές το εκτελείτε, λέγεται ότι είναι "εξίσου ισχυρό" κάθε φορά - idempotent. Αυτό είναι χρήσιμο για την αυτόματη επανάληψη αιτήσεων. Δεν είστε πλέον "είστε βέβαιοι ότι θέλετε να ξαναστείλετε" όταν πιέζετε το κουμπί "πίσω" στο πρόγραμμα περιήγησης.

Μια γενική συμβουλή είναι να χρησιμοποιήσετε τοPOST όταν χρειάζεστε το διακομιστή να ελέγχει την παραγωγή URL των πόρων σας. Χρησιμοποιήστε το PUT αλλιώς. Προτιμήστε το PUT πέρα ​​από το POST.

163
Alexander Torstling

Χρησιμοποιήστε το POST για να δημιουργήσετε και PUT για ενημέρωση. Αυτό συμβαίνει με τον Ruby on Rails.

PUT    /items/1      #=> update
POST   /items        #=> create
121
Tim Sullivan

Και οι δύο χρησιμοποιούνται για τη μετάδοση δεδομένων μεταξύ πελάτη-διακομιστή, αλλά υπάρχουν και λεπτές διαφορές μεταξύ τους, οι οποίες είναι:

Enter image description here

Αναλογία:

  • PUT δηλ. Πάρτε και βάλτε όπου ήταν.
  • POST ως αποστολή αλληλογραφίας στο post γραφείο.

enter image description here

Κοινωνικά Μέσα/Δίκτυο Αναλογία:

  • Δημοσίευση στα κοινωνικά μέσα: όταν δημοσιεύουμε μήνυμα, δημιουργεί νέα δημοσίευση.
  • Βάλτε (δηλ. Επεξεργαστείτε) για το μήνυμα που έχουμε ήδη δημοσιεύσει.
96
Premraj

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

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

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

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

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

65
Jörg W Mittag

Εν συντομία:

PUT είναι idempotent, όπου η κατάσταση πόρων θα είναι η ίδια εάν εκτελείται η ίδια ενέργεια μία φορά ή πολλές φορές.

POST είναι μη-εικονική, όπου η κατάσταση του πόρου μπορεί να γίνει διαφορετική εάν η λειτουργία εκτελείται πολλές φορές σε σύγκριση με την εκτέλεση μιας μόνο χρονικής στιγμής.

Αναλογία με ερώτημα βάσης δεδομένων

PUT Μπορείτε να σκεφτείτε παρόμοια με "UPDATE STUDENT SET διεύθυνση =" abc "όπου id =" 123 "?

POST Μπορείτε να σκεφτείτε κάτι σαν "ΕΙΣΑΓΩΓΗ ΣΤΟ ΜΕΛΛΟΝ (όνομα, διεύθυνση) ΑΞΙΕΣ (" abc "," xyzzz ");

Το αναγνωριστικό σπουδαστών δημιουργείται αυτόματα.

Με το PUT, εάν το ίδιο ερώτημα εκτελείται πολλές φορές ή μία φορά, η κατάσταση του πίνακα STUDENT παραμένει η ίδια.

Σε περίπτωση POST, εάν το ίδιο ερώτημα εκτελείται πολλές φορές, τότε δημιουργούνται πολλαπλές εγγραφές Φοιτητών στη βάση δεδομένων και αλλαγές στην κατάσταση της βάσης δεδομένων σε κάθε εκτέλεση ενός ερωτήματος "INSERT".

ΣΗΜΕΙΩΣΗ: Το PUT χρειάζεται μια θέση πόρου (ήδη-πόρο) για την οποία πρέπει να γίνει η ενημέρωση, ενώ οPOST δεν το απαιτεί. Επομένως, διαισθητικά POST προορίζεται για τη δημιουργία ενός νέου πόρου, ενώ το PUT απαιτείται για την ενημέρωση του ήδη υπάρχοντος πόρου.

Κάποιοι μπορεί να βρουν ότι οι ενημερώσεις μπορούν να πραγματοποιηθούν με POST. Δεν υπάρχει κανένας σκληρός κανόνας ποιος κάποιος θα χρησιμοποιήσει για ενημερώσεις ή ποιος θα χρησιμοποιηθεί για τη δημιουργία. Και πάλι αυτές οι συμβάσεις, και διαισθητικά είμαι διατεθειμένη με την παραπάνω συλλογιστική και την ακολουθώ .

45
bharatj

Το POST είναι σαν να τοποθετείτε μια επιστολή σε ένα γραμματοκιβώτιο ή να δημοσιεύετε ένα μήνυμα ηλεκτρονικού ταχυδρομείου σε μια ουρά μηνυμάτων ηλεκτρονικού ταχυδρομείου. Το PUT είναι σαν να βάζετε ένα αντικείμενο σε μια τρύπα ή μια θέση σε ένα ράφι (έχει μια γνωστή διεύθυνση).

Με το POST, δημοσιεύετε τη διεύθυνση του QUEUE ή της COLLECTION. Με το PUT, τοποθετείτε τη διεύθυνση του στοιχείου.

Το PUT είναι idempotent. Μπορείτε να στείλετε το αίτημα 100 φορές και δεν θα έχει σημασία. POST δεν είναι idempotent. Εάν στείλετε το αίτημα 100 φορές, θα λάβετε 100 μηνύματα ηλεκτρονικού ταχυδρομείου ή 100 γράμματα στο ταχυδρομικό σας κουτί.

Ένας γενικός κανόνας: αν γνωρίζετε την ταυτότητα ή το όνομα του αντικειμένου, χρησιμοποιήστε το PUT. Εάν θέλετε το αναγνωριστικό ή το όνομα του αντικειμένου να ανατεθεί από το μέρος που το λαμβάνει, χρησιμοποιήστε το POST.

POST versus PUT

42
Homer6

Νέα απάντηση (τώρα που καταλαβαίνω REST καλύτερα):

Το PUT είναι απλώς μια δήλωση του περιεχομένου που η υπηρεσία θα πρέπει από τώρα και στο εξής να χρησιμοποιεί για την αναπαραγωγή των πόρων που προσδιορίζονται από τον πελάτη. POST είναι μια δήλωση του περιεχομένου της υπηρεσίας, από τώρα και στο εξής, να περιέχει (ενδεχομένως, διπλότυπο), αλλά εξαρτάται από το διακομιστή πώς να προσδιορίσει αυτό το περιεχόμενο.

PUT x (αν το x προσδιορίζει ένα resource ): "Αντικαταστήστε το περιεχόμενο του πόρου που προσδιορίστηκε από το x με το περιεχόμενό μου".

PUT x (αν το x δεν εντοπίζει έναν πόρο): "Δημιουργήστε έναν νέο πόρο που περιέχει το περιεχόμενό μου και χρησιμοποιήστε το x για να το προσδιορίσετε".

POST x: "Αποθηκεύστε το περιεχόμενό μου και δώστε μου ένα αναγνωριστικό που μπορώ να χρησιμοποιήσω για να προσδιορίσω έναν πόρο (παλιό ή καινούργιο) που περιέχει το αναφερθέν περιεχόμενο (ενδεχομένως αναμεμειγμένο με άλλο περιεχόμενο)." "Αυτός ο πόρος πρέπει να είναι πανομοιότυπος ή υποδεέστερος προς εκείνον που προσδιορίζει το x". " y ο πόρος είναι δευτερεύων στον πόρο x είναι τυπικά, αλλά όχι απαραίτητα, υλοποιώντας κάνοντας ) + y μια υποδιαδρομή της x (π.χ. x = /foo και y = /foo/bar) και τροποποιώντας την αντιπροσώπευση του πόρου x για να αντικατοπτρίζει την ύπαρξη ενός νέου πόρου, π.χ. με μια υπερ-σύνδεση με τον πόρο y και μερικά μεταδεδομένα. Μόνο ο τελευταίος είναι πραγματικά απαραίτητος για τον καλό σχεδιασμό, καθώς οι διευθύνσεις URL είναι αδιαφανείς στο REST - υποτίθεται ότι χρήση hypermedia αντί της κατασκευής URL από την πλευρά του πελάτη για να διασχίσει την υπηρεσία ούτως ή άλλως .

Στο REST, δεν υπάρχει κανένας πόρος που να περιέχει "περιεχόμενο". Αναφέρομαι ως "περιεχόμενο" σε δεδομένα που χρησιμοποιεί η υπηρεσία για να κάνει τις αναπαραστάσεις με συνέπεια. Συνήθως αποτελείται από ορισμένες σχετικές σειρές σε μια βάση δεδομένων ή ένα αρχείο (π.χ. ένα αρχείο εικόνας). Εναπόκειται στην υπηρεσία να μετατρέψει το περιεχόμενο του χρήστη σε κάτι που μπορεί να χρησιμοποιήσει η υπηρεσία, π.χ. μετατροπή ενός ωφέλιμου φορτίου JSON σε δηλώσεις SQL.

Αρχική απάντηση (ίσως είναι πιο εύκολη στην ανάγνωση) :

PUT /something (αν το /something υπάρχει ήδη): "Πάρτε ό, τι έχετε στο /something και αντικαταστήστε το με αυτό που σας δίνω".

PUT /something (αν το /something δεν υπάρχει ήδη): "Πάρτε αυτό που σας δίνω και το βάλετε στο /something."

POST /something: "Πάρτε αυτό που σας δίνω και το βάζετε οπουδήποτε θέλετε κάτω από το /something αρκεί να μου δώσετε τη διεύθυνση URL του όταν τελειώσετε."

38
Jordan

Σύντομη Απάντηση:

Απλός κανόνας: Χρησιμοποιήστε POST για να δημιουργήσετε, χρησιμοποιήστε το PUT για ενημέρωση.

Μεγάλη Απάντηση:

ΘΕΣΗ:

  • Το POST χρησιμοποιείται για την αποστολή δεδομένων στο διακομιστή.
  • Χρήσιμο όταν η διεύθυνση URL του πόρου είναι άγνωστη

ΒΑΖΩ:

  • Το PUT χρησιμοποιείται για τη μεταφορά της κατάστασης στο διακομιστή
  • Χρήσιμο όταν είναι γνωστή η διεύθυνση URL ενός πόρου

Μεγαλύτερη Απάντηση:

Για να το καταλάβουμε πρέπει να αναρωτηθούμε γιατί χρειάστηκε το PUT, ποια ήταν τα προβλήματα που το PUT προσπαθούσε να επιλύσει αυτό POST δεν μπορούσε.

Από την άποψη της αρχιτεκτονικής REST αρχιτεκτονικής δεν έχει σημασία τίποτα. Θα μπορούσαμε να ζήσαμε και χωρίς PUT. Αλλά από την άποψη του προγραμματιστή του πελάτη, έκανε τη ζωή του πολύ απλούστερη.

Πριν από το PUT, οι πελάτες δεν ήταν σε θέση να γνωρίζουν άμεσα τη διεύθυνση URL που δημιούργησε ο διακομιστής ή αν είχαν δημιουργήσει όλα αυτά ή αν τα δεδομένα που θα αποστέλλονταν στον διακομιστή έχουν ήδη ενημερωθεί ή όχι. Το PUT ανακούφισε τον υπεύθυνο ανάπτυξης όλων αυτών των πονοκεφάλων. Το PUT είναι idempotent, το PUT χειρίζεται τις συνθήκες αγώνα και το PUT επιτρέπει στον πελάτη να επιλέξει τη διεύθυνση URL.

37
ishandutta2007

Το Ruby on Rails 4.0 θα χρησιμοποιήσει τη μέθοδο 'PATCH' αντί για PUT για να κάνει μερικές ενημερώσεις.

Το RFC 5789 λέει για το PATCH (από το 1995):

Απαιτείται μια νέα μέθοδος για τη βελτίωση της διαλειτουργικότητας και την πρόληψη σφαλμάτων. Η μέθοδος PUT έχει ήδη οριστεί για να αντικαταστήσει έναν πόρο με ένα νέο νέο σώμα και δεν μπορεί να επαναχρησιμοποιηθεί για να κάνει μερικές αλλαγές. Διαφορετικά, οι διακομιστές μεσολάβησης και οι προσωρινές μνήμες, ακόμα και οι πελάτες και οι διακομιστές, μπορεί να μπερδευτούν ως προς το αποτέλεσμα της λειτουργίας. POST χρησιμοποιείται ήδη αλλά χωρίς ευρεία διαλειτουργικότητα (για τον ένα, δεν υπάρχει κανένας τυποποιημένος τρόπος για την εύρεση υποστήριξης μορφής patch). Το PATCH αναφέρθηκε σε προηγούμενες προδιαγραφές HTTP, αλλά δεν έχει οριστεί πλήρως.

" Edge Rails: PATCH είναι η νέα κύρια μέθοδος HTTP για ενημερώσεις " εξηγεί αυτό.

35
germanlinux

Με τον κίνδυνο επαναφοράς των όσων έχουν ήδη ειπωθεί, φαίνεται σημαντικό να θυμηθούμε ότι PUT υπονοεί ότι ο πελάτης ελέγχει τι είναι URL είναι θα καταλήξει να είναι, κατά τη δημιουργία ενός πόρου. Έτσι μέρος της επιλογής μεταξύ PUT και POST πρόκειται να είναι για το πόσο μπορείτε να εμπιστευτείτε τον πελάτη για να παρέχει σωστή, κανονικοποιημένη URL που είναι συνεπείς με ό, τι και αν είναι το σχέδιό σας URL.

Όταν δεν μπορείτε να εμπιστεύεστε πλήρως τον πελάτη να κάνει το σωστό, θα ήταν πιο ενδεδειγμένο να χρησιμοποιήσετε POST για να δημιουργήσετε ένα νέο στοιχείο και στη συνέχεια να στείλετε την διεύθυνση URL πίσω στον πελάτη στην απάντηση.

27
skillet-thief

Με πολύ απλό τρόπο παίρνω το παράδειγμα της γραμμής του Facebook.

Περίπτωση 1: Όταν δημοσιεύετε κάτι στο χρονικό σας πλαίσιο, είναι μια νέα νέα καταχώρηση. Έτσι, σε αυτή την περίπτωση χρησιμοποιούν τη μέθοδο POST επειδή η μέθοδος POST δεν είναι μη εξουσιοδοτημένη.

Περίπτωση 2: Εάν ο φίλος σας σχολιάσει την ανάρτηση σας την πρώτη φορά, αυτό επίσης θα δημιουργήσει μια νέα καταχώρηση στη βάση δεδομένων, ώστε να χρησιμοποιηθεί η μέθοδος POST.

Περίπτωση 3: Εάν ο φίλος σας επεξεργαστεί το σχόλιό του, στην περίπτωση αυτή, είχαν ένα σχόλιο id, ώστε να ενημερώσουν ένα υπάρχον σχόλιο αντί να δημιουργήσουν μια νέα καταχώρηση στη βάση δεδομένων. Επομένως, για αυτόν τον τύπο λειτουργίας χρησιμοποιήστε τη μέθοδο PUT επειδή είναι idempotent. *

Σε μια γραμμή, χρησιμοποιήστε POST για να προσθέσετε μια νέα καταχώρηση στη βάση δεδομένων και PUT σε pdate = κάτι στη βάση δεδομένων.

21
UniCoder

Το πιο σημαντικό θέμα είναι αξιοπιστία. Εάν χάσει ένα μήνυμαPOST, η κατάσταση του συστήματος είναι απροσδιόριστη. Η αυτόματη ανάκτηση είναι αδύνατη. Για τα μηνύματα PUT, η κατάσταση είναι απροσδιόριστη μόνο μέχρι την πρώτη επιτυχή επανάληψη.

Για παράδειγμα, μπορεί να μην είναι καλή ιδέα να δημιουργήσετε συναλλαγές με πιστωτικές κάρτες με POST.

Αν τυχαίνει να έχετε δημιουργήσει αυτόματα URI στον πόρο σας, μπορείτε ακόμα να χρησιμοποιήσετε το PUT μεταφέροντας ένα παραγόμενο URI (δείχνοντας έναν κενό πόρο) στον πελάτη.

Κάποιες άλλες σκέψεις:

  • Το POST ακυρώνει αποθηκευμένα αντίγραφα ολόκληρου του πόρου που περιέχει (καλύτερη συνέπεια)
  • Οι απαντήσεις PUT δεν είναι αποθηκευμένες στην κρυφή μνήμη ενώ οιPOST είναι (απαιτούν Content-Location και λήξη)
  • Το PUT υποστηρίζεται λιγότερο από π.χ. Java ME, παλαιότερα προγράμματα περιήγησης, firewalls
20
Hans Malherbe

Οι αναγνώστες νέοι σε αυτό το θέμα θα χτυπηθούν από την ατελείωτη συζήτηση για το τι πρέπει να κάνετε και τη σχετική απουσία διδαγμάτων από την εμπειρία. Το γεγονός ότι REST είναι "προτίμησε" πάνω από SOAP είναι, μάλλον, μια μάθηση υψηλού επιπέδου από την εμπειρία, αλλά καλό θα πρέπει να έχουμε προχωρήσει από εκεί; Είναι το 2016. Η διατριβή του Roy ήταν το 2000. Τι έχουμε αναπτύξει; Ειχε πλακα? Ήταν εύκολο να ενσωματωθεί; Για να στηρίξει? Θα χειριστεί την άνοδο των smartphones και τις κινητές συνδέσεις;

Σύμφωνα με τον ME, τα δίκτυα πραγματικής ζωής είναι αναξιόπιστα. Ζητεί χρονικό όριο. Οι συνδέσεις επαναφέρονται. Τα δίκτυα κατεβαίνουν για ώρες ή ημέρες κάθε φορά. Τα τρένα εισέρχονται σε σήραγγες με χρήστες κινητών επιβατών. Για οποιοδήποτε αίτημα (όπως αναγνωρίζεται περιστασιακά σε όλη αυτή τη συζήτηση) το αίτημα μπορεί να πέσει στο νερό στο δρόμο του, ή η απόκριση μπορεί να πέσει στο νερό κατά την επιστροφή του. Υπό αυτές τις συνθήκες, η έκδοση PUT, POST και οι αιτήσεις DELETE απέναντι σε ουσιαστικούς πόρους, με χτύπησαν πάντοτε ως λίγο βάναυσο και αφελές.

Το HTTP δεν κάνει τίποτα για να εξασφαλίσει την αξιόπιστη συμπλήρωση της απάντησης αίτησης, και αυτό είναι εντάξει επειδή αυτό είναι σωστά το έργο των εφαρμογών που έχουν επίγνωση του δικτύου. Αναπτύσσοντας μια τέτοια εφαρμογή, μπορείτε να μεταβείτε στα στεφάνια για να χρησιμοποιήσετε το PUT αντί για το POST και, στη συνέχεια, περισσότερα σκουλήκια για να δώσετε ένα συγκεκριμένο είδος σφάλματος στο διακομιστή αν ανιχνεύσετε διπλότυπα αιτήματα. Πίσω στον πελάτη, πρέπει στη συνέχεια να περάσετε από τα στεφάνια για να ερμηνεύσετε αυτά τα λάθη, να επαναδημιουργήσετε, να επικυρώσετε και να επαναλάβετε.

Ή μπορείτε να το κάνετε αυτό: θεωρήστε τα μη ασφαλή αιτήματά σας ως εφήμερους πόρους για ένα χρήστη (ας τους ονομάσουμε ενέργειες). Οι πελάτες ζητούν μια νέα "ενέργεια" σε έναν ουσιαστικό πόρο με κενό POST στον πόρο. POST θα χρησιμοποιηθεί μόνο για αυτό. Αφού ασφαλώς κατέχει το URI της πρόσφατα εκλεπτυσμένης ενέργειας, ο πελάτης PUTs το ανασφαλές αίτημα στο URI ενέργειας, όχι ο πόρος στόχος . Η επίλυση της ενέργειας και η ενημέρωση του "πραγματικού" πόρου είναι σωστά η εργασία του API σας, και εδώ αποσυνδέεται από το αναξιόπιστο δίκτυο.

Ο διακομιστής κάνει την επιχείρηση, επιστρέφει την απάντηση και το αποθηκεύει σε σχέση με το URI της συμφωνηθείσας ενέργειας . Αν κάτι πάει στραβά, ο πελάτης επαναλαμβάνει το αίτημα (φυσική συμπεριφορά!) Και αν ο διακομιστής το έχει ήδη δει, επαναλαμβάνει την αποθηκευμένη απόκριση και δεν κάνει τίποτα άλλο .

Θα παρατηρήσετε γρήγορα την ομοιότητα με τις υποσχέσεις: δημιουργούμε και επιστρέψουμε το σύμβολο κράτησης θέσης για το αποτέλεσμα προτού κάνουμε οτιδήποτε. Επίσης, όπως μια υπόσχεση, μια δράση μπορεί να επιτύχει ή να αποτύχει μία φορά, αλλά το αποτέλεσμα της μπορεί να εξαχθεί επανειλημμένα.

Το καλύτερο από όλα, δίνουμε την ευκαιρία να στέλνουμε και να λαμβάνουμε τις εφαρμογές μια ευκαιρία να συνδέσουμε τη μοναδικά προσδιορισμένη δράση με τη μοναδικότητα στο αντίστοιχο περιβάλλον. Και μπορούμε να αρχίσουμε να απαιτούμε και να επιβάλλουμε !, υπεύθυνη συμπεριφορά από τους πελάτες: να επαναλάβετε τα αιτήματά σας όσο θέλετε, αλλά μην δημιουργείτε νέα ενέργεια έως ότου αποκτήσετε ένα οριστικό αποτέλεσμα από το υπάρχον.

Ως εκ τούτου, πολυάριθμα ακανθώδη προβλήματα πάει μακριά. Οι επαναλαμβανόμενες αιτήσεις εισαγωγής δεν δημιουργούν διπλότυπα και δεν δημιουργούμε τον πραγματικό πόρο μέχρι να έχουμε τα δεδομένα. (οι στήλες βάσης δεδομένων μπορούν να παραμείνουν μη-μηδενικές). Τα αιτήματα επανειλημμένης ενημέρωσης δεν θα χτυπήσουν ασυμβίβαστες καταστάσεις και δεν θα αντικαταστήσουν τις επόμενες αλλαγές. Οι πελάτες μπορούν (εκ νέου) να ανακτήσουν και να επεξεργαστούν χωρίς προβλήματα την αρχική επιβεβαίωση για οποιοδήποτε λόγο (ο πελάτης συνέτριψε, η απάντηση εξαφανίστηκε κλπ.).

Διαδοχικά αιτήματα διαγραφής μπορούν να δουν και να επεξεργαστούν την αρχική επιβεβαίωση, χωρίς να χτυπήσουν ένα σφάλμα 404. Εάν τα πράγματα διαρκούν περισσότερο από το αναμενόμενο, μπορούμε να απαντήσουμε προσωρινά και έχουμε έναν χώρο όπου ο πελάτης μπορεί να ελέγξει για το οριστικό αποτέλεσμα. Το ωραιότερο μέρος αυτού του μοντέλου είναι η ιδιοκτησία του Kung-Fu (Panda). Παίρνουμε μια αδυναμία, την τάση των πελατών να επαναλαμβάνουν ένα αίτημα οποτεδήποτε δεν καταλαβαίνουν την απάντηση και να την μετατρέψουν σε μια δύναμη :-)

Πριν μου πει ότι αυτό δεν είναι ΑΠΟΛΥΤΕΡΗ, παρακαλώ σκεφτείτε τους πολυάριθμους τρόπους με τους οποίους REST αρχές τηρούνται. Οι πελάτες δεν κατασκευάζουν διευθύνσεις URL. Το API παραμένει ανιχνεύσιμο, αν και με μικρή αλλαγή στη σημασιολογία. Τα ρήματα HTTP χρησιμοποιούνται κατάλληλα. Αν νομίζετε ότι πρόκειται για τεράστια αλλαγή στην εφαρμογή, μπορώ να σας πω από την εμπειρία ότι δεν είναι.

Αν νομίζετε ότι θα έχετε τεράστια ποσά δεδομένων για αποθήκευση, ας μιλήσουμε για τόμους: μια τυπική επιβεβαίωση ενημέρωσης είναι ένα κλάσμα ενός κιλοβάτ. Το HTTP σας δίνει ένα ή δύο λεπτά για να απαντήσετε οριστικά. Ακόμη και αν αποθηκεύετε μόνο ενέργειες για μια εβδομάδα, οι πελάτες έχουν αρκετές πιθανότητες να καλύψουν τη διαφορά. Εάν έχετε πολύ μεγάλους όγκους, μπορεί να θέλετε να έχετε μια αποκλειστική τιμή αποθήκευσης βασικών τιμών συμβατή με οξύ ή μια λύση στη μνήμη.

14
bbsimonbb

Φαίνεται πάντα να υπάρχει κάποια σύγχυση ως προς το πότε να χρησιμοποιείτε τη μέθοδο HTTP POST έναντι της μεθόδου HTTP PUT για υπηρεσίες REST. Οι περισσότεροι προγραμματιστές θα προσπαθήσουν να συνδέσουν τις λειτουργίες CRUD απευθείας με τις μεθόδους HTTP. Θα υποστηρίξω ότι αυτό δεν είναι σωστό και δεν μπορεί κανείς απλώς να συνδέσει τις έννοιες CRUD με τις μεθόδους HTTP. Αυτό είναι:

Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE

Είναι αλήθεια ότι οι λειτουργίες R(etrieve) και D(elete) των λειτουργιών CRUD μπορούν να αντιστοιχιστούν απευθείας στις μεθόδους HTTP GET και DELETE αντίστοιχα. Ωστόσο, η σύγχυση βρίσκεται στις λειτουργίες C(reate) και U(update). Σε ορισμένες περιπτώσεις, μπορεί κανείς να χρησιμοποιήσει το PUT για δημιουργία, ενώ σε άλλες περιπτώσεις θα απαιτηθεί ένα POST. Η ασάφεια έγκειται στον ορισμό μιας μεθόδου HTTP PUT έναντι μιας μεθόδου HTTP POST.

Σύμφωνα με τις προδιαγραφές HTTP 1.1 οι μέθοδοι GET, HEAD, DELETE και PUT πρέπει να είναι idempotent, και η μέθοδος POST δεν είναι idempotent. Αυτό σημαίνει ότι μια πράξη είναι ανεξάρτητη εάν μπορεί να εκτελεστεί σε έναν πόρο μία ή πολλές φορές και να επιστρέψει πάντα την ίδια κατάσταση αυτού του πόρου. Ενώ μια μη εξουσιοδοτημένη λειτουργία μπορεί να επιστρέψει μια τροποποιημένη κατάσταση του πόρου από το ένα αίτημα στο άλλο. Ως εκ τούτου, σε μια μη εξουσιοδοτημένη λειτουργία, δεν υπάρχει εγγύηση ότι κάποιος θα λάβει την ίδια κατάσταση ενός πόρου.

Με βάση τον παραπάνω εξειδικευμένο ορισμό, η χρήση της μεθόδου HTTP PUT σε σχέση με τη χρήση της μεθόδου HTTP POST για υπηρεσίες REST είναι: Χρησιμοποιήστε τη μέθοδο HTTP PUT όταν:

The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).

Και στις δύο περιπτώσεις, αυτές οι λειτουργίες μπορούν να εκτελεστούν πολλές φορές με τα ίδια αποτελέσματα. Αυτός είναι ο πόρος δεν θα αλλάξει ζητώντας τη λειτουργία περισσότερες από μία φορές. Ως εκ τούτου, μια πραγματική εγχώρια λειτουργία. Χρησιμοποιήστε τη μέθοδο HTTP POST όταν:

The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.

Συμπέρασμα

Μην συσχετίζετε άμεσα και αντιστοιχίζετε λειτουργίες CRUD με μεθόδους HTTP για υπηρεσίες REST. Η χρήση μιας μεθόδου HTTP PUT έναντι μιας μεθόδου HTTP POST θα πρέπει να βασίζεται στην ιδιότυπη πτυχή αυτής της λειτουργίας. Δηλαδή, αν η λειτουργία είναι idempotent, τότε χρησιμοποιήστε τη μέθοδο HTTP PUT. Εάν η λειτουργία δεν είναι ενεργή, χρησιμοποιήστε τη μέθοδο HTTP POST.

14
Burhan

ο διακομιστής προέλευσης μπορεί να δημιουργήσει τον πόρο με αυτό το URI

Έτσι, χρησιμοποιείτε το POST και πιθανόν, αλλά όχι απαραίτητο, για τη δημιουργία πόρων. Δεν χρειάζεται να υποστηρίξετε και τα δύο. Για μένα το POST είναι απόλυτα αρκετό. Είναι λοιπόν μια απόφαση σχεδιασμού.

Όπως αναφέρθηκε στην απόφασή σας, χρησιμοποιείτε PUT για τη δημιουργία δεν υπάρχει πόρος που έχει αποδοθεί σε ένα IRI, και θέλετε να δημιουργήσετε έναν πόρο ούτως ή άλλως. Για παράδειγμα, ο PUT /users/123/password συνήθως αντικαθιστά τον παλιό κωδικό πρόσβασης με έναν νέο, αλλά μπορείτε να τον χρησιμοποιήσετε για να δημιουργήσετε έναν κωδικό πρόσβασης εάν δεν υπάρχει ήδη (για παράδειγμα, από πρόσφατα εγγεγραμμένους χρήστες ή αποκαθιστώντας τους απαγορευμένους χρήστες).

13
inf3rno

Θα προσγειωθώ με τα εξής:

Το PUT αναφέρεται σε έναν πόρο που προσδιορίζεται από το URI. Σε αυτήν την περίπτωση, την ενημερώνετε. Είναι το μέρος των τριών ρήματα που αναφέρονται στους πόρους - διαγράψτε και πάρτε τα άλλα δύο.

Το POST είναι βασικά ένα μήνυμα ελεύθερης φόρμας, με το νόημά του να ορίζεται "εκτός ζώνης". Εάν το μήνυμα μπορεί να ερμηνευτεί ως προσθήκη ενός πόρου σε έναν κατάλογο, αυτό θα ήταν εντάξει, αλλά βασικά πρέπει να καταλάβετε το μήνυμα που στέλνετε (απόσπαση) για να μάθετε τι θα συμβεί με τον πόρο.


Επειδή τα PUT και GET και DELETE αναφέρονται σε έναν πόρο, είναι επίσης εξ ορισμού idempotent.

Το POST μπορεί να εκτελέσει τις άλλες τρεις λειτουργίες, αλλά στη συνέχεια η σημασιολογία του αιτήματος θα χαθεί στους διαμεσολαβητές όπως οι κρυφές μνήμες και οι πληρεξούσιοι. Αυτό ισχύει και για την παροχή ασφάλειας στον πόρο, δεδομένου ότι το URI μιας θέσης δεν υποδεικνύει απαραίτητα τον πόρο στον οποίο υποβάλλει αίτηση (μπορεί όμως).

Ένα PUT δεν χρειάζεται να είναι μια δημιουργία? η υπηρεσία θα μπορούσε να σφάλσει εάν ο πόρος δεν έχει ήδη δημιουργηθεί, αλλά με άλλο τρόπο να τον ενημερώσει. Ή αντίστροφα - μπορεί να δημιουργήσει τον πόρο, αλλά να μην επιτρέψει ενημερώσεις. Το μόνο που απαιτείται για το PUT είναι ότι δείχνει έναν συγκεκριμένο πόρο και το ωφέλιμο φορτίο του είναι η αναπαράσταση αυτού του πόρου. Ένα επιτυχημένο PUT σημαίνει (παρεμπόδιση παρεμβολής) ότι ένα GET θα ανακτήσει τον ίδιο πόρο.


Επεξεργασία: Ένα ακόμα πράγμα - ένα PUT μπορεί να δημιουργήσει, αλλά αν το κάνει τότε το ID πρέπει να είναι ένα φυσικό ID - AKA μια διεύθυνση ηλεκτρονικού ταχυδρομείου. Με αυτόν τον τρόπο, όταν PUT δύο φορές, το δεύτερο put είναι μια ενημέρωση του πρώτου. Αυτό το κάνει idempotent.

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

11
Gerard ONeill

Εκτός από τις διαφορές που προτείνονται από άλλους, θέλω να προσθέσω ένα ακόμα.

Στη μέθοδο POST μπορείτε να στείλετε παραμέτρους σώματος στο form-data

Στη μέθοδο PUT πρέπει να στείλετε παραμέτρους σώματος στο x-www-form-urlencoded

Κεφαλίδα Content-Type:application/x-www-form-urlencoded

Σύμφωνα με αυτό, δεν μπορείτε να στείλετε αρχεία ή δεδομένα πολλαπλών τμημάτων στη μέθοδο PUT

ΕΠΕΞΕΡΓΑΣΤΕΊΤΕ

Ο τύπος περιεχομένου "application/x-www-form-urlencoded" είναι αναποτελεσματικός για την αποστολή μεγάλων ποσοτήτων δυαδικών δεδομένων ή κειμένου που περιέχουν χαρακτήρες που δεν είναι ASCII. Ο τύπος περιεχομένου "multipart/form-data" θα πρέπει να χρησιμοποιείται για την υποβολή εντύπων που περιέχουν αρχεία, μη ASCII δεδομένα και δυαδικά δεδομένα.

Αυτό σημαίνει αν πρέπει να υποβάλετε

αρχεία, μη ASCII δεδομένα και δυαδικά δεδομένα

θα πρέπει να χρησιμοποιήσετε τη μέθοδο POST

11
Rohit Dhiman

Η σημασιολογία υποτίθεται ότι είναι διαφορετική, καθώς το "PUT", όπως το "GET" υποτίθεται ότι είναι idempotent - σημαίνει ότι μπορείτε να κάνετε την ίδια ακριβώς αίτηση PUT πολλές φορές και το αποτέλεσμα θα είναι σαν να το εκτελέσατε μόνο μία φορά.

Θα περιγράψω τις συμβάσεις που νομίζω ότι χρησιμοποιούνται ευρύτερα και είναι πιο χρήσιμες:

Όταν κάνετε PUT έναν πόρο σε μια συγκεκριμένη διεύθυνση URL, αυτό που συμβαίνει είναι ότι θα πρέπει να αποθηκευτεί σε εκείνη τη διεύθυνση URL ή κάτι παρόμοιο με αυτές τις γραμμές.

Όταν POST σε έναν πόρο σε μια συγκεκριμένη διεύθυνση URL, συχνά δημοσιεύετε μια σχετική πληροφορία σε αυτή τη διεύθυνση URL. Αυτό σημαίνει ότι ο πόρος στη διεύθυνση URL υπάρχει ήδη.

Για παράδειγμα, όταν θέλετε να δημιουργήσετε μια νέα ροή, μπορείτε να την πληκτρολογήσετε σε κάποια διεύθυνση URL. Αλλά όταν θέλετε να POST ένα μήνυμα σε μια υπάρχουσα ροή, μπορείτε POST στη διεύθυνση URL της.

Όσο για την τροποποίηση των ιδιοτήτων του ρεύματος, μπορείτε να το κάνετε με PUT ή POST. Βασικά, χρησιμοποιήστε μόνο "PUT" όταν η λειτουργία είναι idempotent - διαφορετικά χρησιμοποιήστε το POST.

Σημειώστε, ωστόσο, ότι όλα τα σύγχρονα προγράμματα περιήγησης δεν υποστηρίζουν ρήματα HTTP διαφορετικά από GET ή POST.

9
Gregory Magarshak

Τις περισσότερες φορές, θα τις χρησιμοποιήσετε ως εξής:

  • POST ένας πόρος σε μια συλλογή
  • PUT ένας πόρος που προσδιορίζεται από τη συλλογή /: id

Για παράδειγμα:

  • ΜΕΤΆ/στοιχεία
  • PUT/στοιχεία/1234

Και στις δύο περιπτώσεις, το σώμα αιτήσεων περιέχει τα δεδομένα για τον δημιουργό ή την ενημέρωση του πόρου. Θα πρέπει να είναι προφανές από τα ονόματα των διαδρομών ότι το POST δεν είναι idempotent (αν το ονομάζετε 3 φορές θα δημιουργήσει 3 αντικείμενα), αλλά το PUT είναι idempotent (αν το αποκαλείτε 3 φορές το αποτέλεσμα είναι το ίδιο) . Το PUT χρησιμοποιείται συχνά για λειτουργία "upsert" (δημιουργία ή ενημέρωση), αλλά πάντα μπορείτε να επιστρέψετε ένα σφάλμα 404 εάν θέλετε να το χρησιμοποιήσετε μόνο για να το τροποποιήσετε.

Σημειώστε ότι το POST "δημιουργεί" ένα νέο στοιχείο στη συλλογή και το PUT "αντικαθιστά" ένα στοιχείο σε μια δεδομένη διεύθυνση URL, αλλά είναι μια πολύ συνηθισμένη πρακτική να χρησιμοποιείτε PUT για μερικές τροποποιήσεις, μόνο για να ενημερώσετε υπάρχοντες πόρους και να τροποποιήσετε μόνο τα πεδία που περιλαμβάνονται στο σώμα (αγνοώντας τα άλλα πεδία). Αυτό είναι τεχνικά λανθασμένο, αν θέλετε να είστε REST-purist, το PUT θα πρέπει να αντικαταστήσει ολόκληρο τον πόρο και θα πρέπει να χρησιμοποιήσετε το PATCH για τη μερική ενημέρωση. Εγώ προσωπικά δεν ενδιαφέρομαι πολύ όσο η συμπεριφορά είναι σαφής και συνεπής σε όλα τα τελικά σημεία API.

Θυμηθείτε ότι τοREST είναι ένα σύνολο συμβάσεων και οδηγιών για να διατηρείτε απλό το API σας. Εάν καταλήγετε σε μια περίπλοκη εργασία γύρω-γύρω ακριβώς για να ελέγξετε το "RESTful" κουτί τότε θα νικήσει το σκοπό?)

7
tothemario

Ενώ υπάρχει πιθανώς ένας αγνωστικός τρόπος να περιγραφούν αυτά, φαίνεται να έρχεται σε σύγκρουση με διάφορες δηλώσεις από απαντήσεις σε ιστότοπους.

Ας είμαστε πολύ σαφείς και άμεσες εδώ. Εάν είστε προγραμματιστής .NET που συνεργάζεται με το Web API, τα γεγονότα είναι (από την τεκμηρίωση του Microsoft API), http://www.asp.net/web-api/overview/creating-web-apis/creating -a-web-api-that-supports-crud-operations :

1. PUT = UPDATE (/api/products/id)
2. MCSD Exams 2014 -  UPDATE = PUT, there are **NO** multiple answers for that question period.

Βεβαιωθείτε ότι μπορείτε να χρησιμοποιήσετε το "POST" για ενημέρωση, αλλά απλώς ακολουθήστε τις συμβάσεις που προβλέπονται για εσάς με το δεδομένο σας πλαίσιο. Στην περίπτωσή μου είναι. NET/Web API, έτσι PUT είναι για UPDATE δεν υπάρχει συζήτηση.

Ελπίζω ότι αυτό βοηθά όλους τους προγραμματιστές της Microsoft που διαβάζουν όλα τα σχόλια με τους συνδέσμους ιστότοπων Amazon και Sun/Java.

7
Tom Stickel

Ακολουθεί ένας απλός κανόνας:

PUT σε μια διεύθυνση URL θα πρέπει να χρησιμοποιείται για την ενημέρωση ή τη δημιουργία του πόρου που μπορεί να βρίσκεται σε εκείνη τη διεύθυνση URL.

POST σε μια διεύθυνση URL θα πρέπει να χρησιμοποιείται για την ενημέρωση ή τη δημιουργία ενός πόρου που βρίσκεται σε κάποια άλλη διεύθυνση ("δευτερεύοντος") ή δεν μπορεί να εντοπιστεί μέσω HTTP.

6
Adam Griffiths

Εάν γνωρίζετε τις λειτουργίες της βάσης δεδομένων, υπάρχουν

  1. Επιλέγω
  2. Εισάγετε
  3. Εκσυγχρονίζω
  4. Διαγράφω
  5. Συγχώνευση (Ενημέρωση εάν υπάρχει ήδη, αλλιώς εισάγετε)

Χρησιμοποιώ το PUT για τη συγχώνευση και την ενημέρωση όπως οι λειτουργίες και χρησιμοποιήστε το POST για Εισαγωγές.

6
Rajan

Στην πράξη, τοPOST λειτουργεί καλά για τη δημιουργία πόρων. Η διεύθυνση URL του νεοσύστατου πόρου θα πρέπει να επιστραφεί στην κεφαλίδα απόκρισης τοποθεσίας. Το PUT θα πρέπει να χρησιμοποιείται για την πλήρη ενημέρωση ενός πόρου. Λάβετε υπόψη ότι αυτές είναι οι βέλτιστες πρακτικές κατά το σχεδιασμό ενός RESTful API. Η προδιαγραφή HTTP ως τέτοια δεν περιορίζει τη χρήση του PUT/POST με λίγους περιορισμούς για τη δημιουργία/ενημέρωση πόρων. Ρίξτε μια ματιά στο http://techoctave.com/c7/posts/71-Twitter-rest-api-dissected που συνοψίζει τις βέλτιστες πρακτικές.

5
java_geek

POST: Χρησιμοποιήστε το για τη δημιουργία νέων πόρων. Είναι σαν την εντολή INSERT (δήλωση SQL) με αναγνωριστικό αυτόματης αύξησης. Στο τμήμα απάντησης περιέχει ένα νέο αναγνωριστικό.

Το POST χρησιμοποιείται επίσης για την ενημέρωση μιας εγγραφής.

PUT: Χρησιμοποιήστε το για τη δημιουργία ενός νέου πόρου, αλλά εδώ ξέρω το κλειδί ταυτότητας. Είναι σαν το INSERT (δήλωση SQL) όπου ξέρω εκ των προτέρων το κλειδί ταυτότητας. Στο τμήμα απάντησης δεν στέλνει τίποτα.

Το PUT χρησιμοποιείται επίσης για την ενημέρωση ενός πόρου

3
sushil pandey

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

Θα πρέπει να χρησιμοποιήσετε PATCH. Μπορείτε PATCH τη λίστα των ερωτήσεων όπως

PATCH /questions HTTP/1.1

με μια λίστα που περιέχει το αντικείμενο που θέλετε να δημιουργηθεί όπως

[
    {
        "title": "I said semantics!",
        "content": "Is this serious?",
        "answer": "Not really"
    }
]

Πρόκειται για ένα αίτημα PATCH ως

  • τροποποιείτε τον υπάρχοντα κατάλογο των πόρων χωρίς να παρέχετε ολόκληρο το νέο περιεχόμενο
  • αλλάζετε την κατάσταση της νέας σας ερώτησης από μη υπάρχουσες σε υπάρχουσες χωρίς την παροχή όλων των δεδομένων (ο διακομιστής πιθανότατα θα προσθέσει id).

Ένα μεγάλο πλεονέκτημα αυτής της μεθόδου είναι ότι μπορείτε να δημιουργήσετε πολλές οντότητες χρησιμοποιώντας ένα μόνο αίτημα, απλά παρέχοντάς τους όλες στη λίστα.

Αυτό είναι κάτι PUT προφανώς δεν μπορεί. Θα μπορούσατε να χρησιμοποιήσετε το POST για τη δημιουργία πολλαπλών οντοτήτων καθώς είναι ο νεροχύτης της κουζίνας του HTTP και μπορεί να κάνει τα πάντα.

Ένα μειονέκτημα είναι ότι πιθανώς κανένας δεν χρησιμοποιεί PATCH αυτόν τον τρόπο. Φοβάμαι, απλά το εφευρέθηκα, αλλά ελπίζω, παρέθεσα μια καλή επιχειρηματολογία.

Θα μπορούσατε να χρησιμοποιήσετε το CREATE, αντίθετα, καθώς επιτρέπονται τα ρήματα HTTP, είναι πιθανό να μην λειτουργούν με κάποια εργαλεία.

Όσον αφορά τη σημασιολογία, CREATE είναι η IMHO η μόνη σωστή επιλογή, οτιδήποτε άλλο είναι ένα τετράγωνο πείρο σε μια στρογγυλή τρύπα. Δυστυχώς, το μόνο που έχουμε είναι στρογγυλές τρύπες.

2
maaartinus