PUT
Μέθοδος HTTP
Προδιαγραφή της μεθόδου HTTP PUT
Η μέθοδος PUT ζητά να δημιουργηθεί ή να αντικατασταθεί η κατάσταση του πόρου-στόχου με την κατάσταση που ορίζεται από την αναπαράσταση που περικλείεται στο ωφέλιμο φορτίο του μηνύματος αίτησης. Μια επιτυχής PUT μιας δεδομένης αναπαράστασης υποδηλώνει ότι μια επακόλουθη GET στον ίδιο πόρο-στόχο θα έχει ως αποτέλεσμα την αποστολή μιας ισοδύναμης αναπαράστασης σε μια απάντηση 200 (OK). Ωστόσο, δεν υπάρχει καμία εγγύηση ότι μια τέτοια αλλαγή κατάστασης θα είναι παρατηρήσιμη, δεδομένου ότι ο πόρος-στόχος μπορεί να επηρεάζεται παράλληλα από άλλους πράκτορες χρήστη ή να υπόκειται σε δυναμική επεξεργασία από τον διακομιστή προέλευσης, πριν ληφθεί οποιαδήποτε επόμενη GET. Μια επιτυχής απόκριση υποδηλώνει μόνο ότι η πρόθεση του πράκτορα χρήστη επιτεύχθηκε κατά τη στιγμή της επεξεργασίας της από τον διακομιστή προέλευσης.
Εάν ο πόρος-στόχος δεν έχει τρέχουσα αναπαράσταση και η PUT δημιουργεί επιτυχώς μία, τότε ο διακομιστής προέλευσης ΠΡΕΠΕΙ να ενημερώσει τον πράκτορα χρήστη στέλνοντας μια απάντηση 201 (Created). Εάν ο πόρος-στόχος διαθέτει τρέχουσα αναπαράσταση και η αναπαράσταση αυτή τροποποιείται επιτυχώς σύμφωνα με την κατάσταση της εσωκλειόμενης αναπαράστασης, τότε ο διακομιστής προέλευσης ΠΡΕΠΕΙ να στείλει είτε μια απάντηση 200 (OK) είτε μια απάντηση 204 (No Content) για να δηλώσει την επιτυχή ολοκλήρωση της αίτησης.
Ένας διακομιστής προέλευσης ΠΡΕΠΕΙ να αγνοεί μη αναγνωρισμένα πεδία επικεφαλίδας που λαμβάνονται σε μια αίτηση PUT (δηλ, δεν τα αποθηκεύει ως μέρος της κατάστασης του πόρου).
Ένας διακομιστής προέλευσης ΠΡΕΠΕΙ να επαληθεύει ότι η αναπαράσταση PUT είναι συνεπής με τυχόν περιορισμούς που έχει ο διακομιστής για τον πόρο-στόχο, οι οποίοι δεν μπορούν ή δεν θα αλλάξουν από την PUT. Αυτό είναι ιδιαίτερα σημαντικό όταν ο διακομιστής προέλευσης χρησιμοποιεί εσωτερικές πληροφορίες διαμόρφωσης που σχετίζονται με το URI προκειμένου να ορίσει τις τιμές για τα μεταδεδομένα αναπαράστασης στις αποκρίσεις GET. Όταν μια αναπαράσταση PUT δεν είναι συνεπής με τον πόρο-στόχο, ο διακομιστής προέλευσης ΠΡΕΠΕΙ είτε να τις κάνει συνεκτικές, μετασχηματίζοντας την αναπαράσταση ή αλλάζοντας τη διαμόρφωση του πόρου, είτε να απαντήσει με κατάλληλο μήνυμα σφάλματος που περιέχει επαρκείς πληροφορίες για να εξηγήσει γιατί η αναπαράσταση είναι ακατάλληλη. Προτείνονται οι κωδικοί κατάστασης 409 (Σύγκρουση) ή 415 (Μη υποστηριζόμενος τύπος πολυμέσων), με τον τελευταίο να αφορά ειδικά τους περιορισμούς στις τιμές Content-Type.
Για παράδειγμα, εάν ο πόρος-στόχος έχει ρυθμιστεί ώστε να έχει πάντα Content-Type "text/html" και η αναπαράσταση που γίνεται PUT έχει Content-Type "image/jpeg", ο διακομιστής προέλευσης θα πρέπει να κάνει ένα από τα εξής:
- a. να αναδιαμορφώσει τον πόρο-στόχο ώστε να αντικατοπτρίζει τον νέο τύπο πολυμέσων;
- β. να μετατρέψει την αναπαράσταση PUT σε μορφή που να συνάδει με εκείνη του πόρου πριν την αποθηκεύσει ως νέα κατάσταση του πόρου- ή,
- γ. να απορρίψετε το αίτημα με μια απάντηση 415 (μη υποστηριζόμενος τύπος πολυμέσων) που υποδεικνύει ότι ο πόρος-στόχος περιορίζεται σε "text/html", περιλαμβάνοντας ίσως έναν σύνδεσμο προς έναν διαφορετικό πόρο που θα ήταν κατάλληλος στόχος για τη νέα αναπαράσταση.
Το HTTP δεν ορίζει ακριβώς πώς μια μέθοδος PUT επηρεάζει την κατάσταση ενός διακομιστή προέλευσης πέρα από αυτό που μπορεί να εκφραστεί από την πρόθεση του αιτήματος του πράκτορα χρήστη και τη σημασιολογία της απάντησης του διακομιστή προέλευσης. Δεν ορίζει τι μπορεί να είναι ένας πόρος, με οποιαδήποτε έννοια αυτής της λέξης, πέρα από τη διεπαφή που παρέχεται μέσω του HTTP. Δεν ορίζει πώς "αποθηκεύεται" η κατάσταση του πόρου, ούτε πώς μπορεί να αλλάξει η αποθήκευση αυτή ως αποτέλεσμα μιας αλλαγής στην κατάσταση του πόρου, ούτε πώς ο διακομιστής προέλευσης μεταφράζει την κατάσταση του πόρου σε αναπαραστάσεις. Σε γενικές γραμμές, όλες οι λεπτομέρειες υλοποίησης πίσω από τη διεπαφή πόρου αποκρύπτονται σκόπιμα από το διακομιστή.
Ένας διακομιστής προέλευσης ΔΕΝ ΠΡΕΠΕΙ να στείλει ένα πεδίο επικεφαλίδας επικυρωτή (ενότητα 7.2), όπως ένα πεδίο ETag ή Last-Modified, σε μια επιτυχή απάντηση σε PUT, εκτός εάν τα δεδομένα αναπαράστασης της αίτησης αποθηκεύτηκαν χωρίς να εφαρμοστεί μετασχηματισμός στο σώμα (δηλαδή, τα νέα δεδομένα αναπαράστασης του πόρου είναι πανομοιότυπα με τα δεδομένα αναπαράστασης που ελήφθησαν στην αίτηση PUT) και η τιμή του πεδίου επικυρωτή αντικατοπτρίζει τη νέα αναπαράσταση. Αυτή η απαίτηση επιτρέπει σε έναν πράκτορα χρήστη να γνωρίζει πότε το σώμα αναπαράστασης που έχει στη μνήμη του παραμένει επίκαιρο ως αποτέλεσμα της PUT, άρα δεν χρειάζεται να ανακτηθεί εκ νέου από τον διακομιστή προέλευσης, και ότι ο νέος επικυρωτής (ή οι νέοι επικυρωτές) που λαμβάνεται στην απόκριση μπορεί να χρησιμοποιηθεί για μελλοντικά αιτήματα υπό όρους, προκειμένου να αποφευχθούν τυχαίες αντικαταστάσεις (ενότητα 5.2).
Η θεμελιώδης διαφορά μεταξύ των μεθόδων POST και PUT αναδεικνύεται από τη διαφορετική πρόθεση για την επισυναπτόμενη αναπαράσταση. Ο πόρος-στόχος σε ένα αίτημα POST προορίζεται να χειριστεί την εσωκλειόμενη αναπαράσταση σύμφωνα με τη σημασιολογία του ίδιου του πόρου, ενώ η εσωκλειόμενη αναπαράσταση σε ένα αίτημα PUT ορίζεται ως αντικατάσταση της κατάστασης του πόρου-στόχου. Ως εκ τούτου, η πρόθεση του PUT είναι ιδιοσυστατική και ορατή στους ενδιάμεσους, παρόλο που το ακριβές αποτέλεσμα είναι γνωστό μόνο στον διακομιστή προέλευσης.
Η ορθή ερμηνεία ενός αιτήματος PUT προϋποθέτει ότι ο πράκτορας χρήστη γνωρίζει ποιος πόρος-στόχος είναι ο επιθυμητός. Μια υπηρεσία που επιλέγει ένα κατάλληλο URI για λογαριασμό του πελάτη, μετά τη λήψη ενός αιτήματος που αλλάζει κατάσταση, ΘΑ ΠΡΕΠΕΙ να υλοποιείται με τη μέθοδο POST και όχι με PUT. Εάν ο διακομιστής προέλευσης δεν θα πραγματοποιήσει την αιτούμενη αλλαγή κατάστασης PUT στον πόρο-στόχο και αντ' αυτού επιθυμεί να εφαρμοστεί σε έναν διαφορετικό πόρο, όπως όταν ο πόρος έχει μετακινηθεί σε διαφορετικό URI, τότε ο διακομιστής προέλευσης ΠΡΕΠΕΙ να στείλει μια κατάλληλη απάντηση 3xx (ανακατεύθυνση)- ο πράκτορας χρήστη ΜΠΟΡΕΙ στη συνέχεια να λάβει τη δική του απόφαση σχετικά με την ανακατεύθυνση ή όχι του αιτήματος.
Ένα αίτημα PUT που εφαρμόζεται στον πόρο-στόχο μπορεί να έχει παρενέργειες σε άλλους πόρους. Για παράδειγμα, ένα άρθρο μπορεί να έχει ένα URI για τον προσδιορισμό της "τρέχουσας έκδοσης" (ένας πόρος), το οποίο είναι ξεχωριστό από τα URI που προσδιορίζουν κάθε συγκεκριμένη έκδοση (διαφορετικοί πόροι που κάποια στιγμή μοιράζονταν την ίδια κατάσταση με τον πόρο της τρέχουσας έκδοσης). Μια επιτυχής αίτηση PUT στο URI "της τρέχουσας έκδοσης" μπορεί επομένως να δημιουργήσει έναν νέο πόρο έκδοσης εκτός από την αλλαγή της κατάστασης του πόρου-στόχου, και μπορεί επίσης να προκαλέσει την προσθήκη συνδέσμων μεταξύ των σχετικών πόρων.
Ένας διακομιστής προέλευσης που επιτρέπει την PUT σε έναν συγκεκριμένο πόρο-στόχο ΠΡΕΠΕΙ να στείλει μια απάντηση 400 (Bad Request) σε μια αίτηση PUT που περιέχει ένα πεδίο κεφαλίδας Content-Range (ενότητα 4.2 του [RFC7233]), καθώς το ωφέλιμο φορτίο είναι πιθανό να είναι μερικό περιεχόμενο που έχει λανθασμένα PUT ως πλήρης αναπαράσταση. Οι μερικές ενημερώσεις περιεχομένου είναι δυνατές με τη στόχευση ενός ξεχωριστά αναγνωρισμένου πόρου με κατάσταση που επικαλύπτει ένα τμήμα του μεγαλύτερου πόρου ή με τη χρήση μιας διαφορετικής μεθόδου που έχει οριστεί ειδικά για μερικές ενημερώσεις (για παράδειγμα, η μέθοδος PATCH που ορίζεται στο [RFC5789]).
Οι απαντήσεις στη μέθοδο PUT δεν μπορούν να αποθηκευτούν στην κρυφή μνήμη. Εάν μια επιτυχής αίτηση PUT περάσει από μια κρυφή μνήμη που έχει μία ή περισσότερες αποθηκευμένες απαντήσεις για το πραγματικό URI της αίτησης, αυτές οι αποθηκευμένες απαντήσεις θα ακυρωθούν (βλ. ενότητα 4.4 του [RFC7234]).
Περιγραφή της μεθόδου PUT
Παράδειγμα για τη μέθοδο HTTP PUT
PUT /data/123 HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/58.0.3029.110 Safari/537
Content-Type: application/json
Accept: application/json
Accept-Language: de-DE,de;q=0.5
Connection: keep-alive
Content-Length: 58
Request body:
{
"id": 123,
"name": "New Name"
}
HTTP/1.1 204 No Content
Date: Mon, 31 July 2023 14:58:12 GMT
Server: Apache/2.4.7 (Ubuntu)
Cache-Control: no-cache