HTTP
HTTP per API
Ricerca…
Osservazioni
Le API HTTP utilizzano un ampio spettro di verbi HTTP e in genere restituiscono risposte JSON o XML.
Crea una risorsa
Non tutti sono d'accordo su quale sia il metodo più semanticamente corretto per la creazione di risorse. Pertanto, la tua API potrebbe accettare richieste POST
o PUT
o entrambe.
Il server dovrebbe rispondere con 201 Created
se la risorsa è stata creata correttamente. Scegli il codice di errore più appropriato se non lo fosse.
Ad esempio, se fornisci un'API per creare record dipendenti, la richiesta / risposta potrebbe essere simile a questa:
POST /employees HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Charlie Smith",
"age": 38,
"job_title": "Software Developer",
"salary": 54895.00
}
HTTP/1.1 201 Created
Location: /employees/1/charlie-smith
Content-Type: application/json
{
"employee": {
"name": "Charlie Smith",
"age": 38,
"job_title": "Software Developer",
"salary": 54895.00
"links": [
{
"uri": "/employees/1/charlie-smith",
"rel": "self",
"method": "GET"
},
{
"uri": "/employees/1/charlie-smith",
"rel": "delete",
"method": "DELETE"
},
{
"uri": "/employees/1/charlie-smith",
"rel": "edit",
"method": "PATCH"
}
]
},
"links": [
{
"uri": "/employees",
"rel": "create",
"method": "POST"
}
]
}
Includendo i links
campi JSON nella risposta consentono al client di accedere alle risorse correlate alla nuova risorsa e all'applicazione nel suo complesso, senza dover prima conoscere i propri URI o metodi.
Modifica una risorsa
La modifica o l'aggiornamento di una risorsa è uno scopo comune per le API. Le modifiche possono essere ottenute inviando le richieste POST
, PUT
o PATCH
alla rispettiva risorsa. Sebbene al POST
sia permesso di aggiungere dati alla rappresentazione esistente di una risorsa, si raccomanda di usare PUT
o PATCH
perché trasmettono una semantica più esplicita.
Il server dovrebbe rispondere con 200 OK
se l'aggiornamento è stato eseguito, o 202 Accepted
se non è ancora stato applicato. Scegli il codice di errore più appropriato se non può essere completato.
Aggiornamenti completi
PUT
ha la semantica di sostituire la rappresentazione corrente con il carico utile incluso nella richiesta. Se il payload non è dello stesso tipo di rappresentazione della rappresentazione corrente della risorsa da aggiornare, il server può decidere quale approccio adottare. RFC7231 definisce che il server può entrambi
- Riconfigurare la risorsa di destinazione in modo che rifletta il nuovo tipo di supporto
- Trasforma la rappresentazione PUT in un formato coerente con quello del resouce prima di salvarlo come nuovo stato della risorsa
- Rifiuta la richiesta con una risposta di
415 Unsupported Media Type
che indica che la risorsa di destinazione è limitata a uno specifico (set) di tipi di supporto.
Una risorsa di base contenente una rappresentazione HAL JSON come ...
{
"name": "Charlie Smith",
"age": 39,
"job_title": "Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
}
}
... potrebbe ricevere una richiesta di aggiornamento come questa
PUT /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 85
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer"
}
Il server può ora sostituire lo stato della risorsa con il corpo della richiesta specificato e anche modificare il tipo di contenuto da application/hal+json
a application/json
o convertire il payload JSON in una rappresentazione HAL JSON e quindi sostituire il contenuto della risorsa con quello trasformato o rifiutare la richiesta di aggiornamento a causa di un tipo di supporto inaplicabile con una risposta di 415 Unsupported Media Type
.
C'è una differenza tra la sostituzione diretta del contenuto o la prima trasformazione della rappresentazione nel modello di rappresentazione definito e quindi la sostituzione del contenuto esistente con quello trasformato. Una successiva richiesta GET
restituirà la seguente risposta su una sostituzione diretta:
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer"
}
mentre l'approccio di trasformazione e quindi di sostituzione restituirà la seguente rappresentazione:
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: e0023aa4e
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
}
}
Effetti collaterali
Nota che PUT
può avere effetti collaterali anche se è definito come operazione idempotent! Questo è documentato in RFC7231 come
Una richiesta PUT applicata alla risorsa di destinazione può avere effetti collaterali su altre risorse . Ad esempio, un articolo potrebbe avere un URI per identificare "la versione corrente" (una risorsa) che è separata dagli URI che identificano ogni particolare versione (diverse risorse che a un certo punto condividevano lo stesso stato della risorsa della versione corrente). Una richiesta PUT riuscita sull'URI della "versione corrente" potrebbe pertanto creare una nuova risorsa di versione oltre a modificare lo stato della risorsa di destinazione e potrebbe anche causare l'aggiunta di collegamenti tra le risorse correlate.
La produzione di voci di registro aggiuntive non è considerata come un effetto collaterale di solito poiché non è certamente uno stato di una risorsa in generale.
Aggiornamenti parziali
RFC7231 menziona questo per quanto riguarda gli aggiornamenti parziali:
Gli aggiornamenti del contenuto parziale sono possibili indirizzando una risorsa identificata separatamente con stato che si sovrappone a una parte della risorsa più grande o utilizzando un metodo diverso che è stato definito in modo specifico per gli aggiornamenti parziali (ad esempio, il metodo PATCH definito in RFC5789 ).
Gli aggiornamenti parziali possono quindi essere eseguiti in due versioni:
- Avere una risorsa incorporare più risorse secondarie più piccole e aggiornare solo una rispettiva risorsa secondaria anziché la risorsa completa tramite
PUT
- Utilizzare
PATCH
ePATCH
al server cosa aggiornare
Aggiornamento parziale con stato di sovrapposizione
Se una rappresentazione utente deve essere parzialmente aggiornata a causa di uno spostamento di un utente in un'altra posizione, invece di aggiornare direttamente l'utente, la risorsa correlata deve essere aggiornata direttamente, il che si riflette in un aggiornamento parziale della rappresentazione dell'utente.
Prima dello spostamento un utente aveva la seguente rappresentazione
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
},
"_embedded": {
"ea:address": {
"street": "Terrace Drive, Central Park",
"zip": "NY 10024"
"city": "New York",
"country": "United States of America",
"_links": {
"self": { "href": "/address/abc" },
"google_maps": { "href": "http://maps.google.com/?ll=40.7739166,-73.970176" }
}
}
}
}
Mentre l'utente si sta spostando in una nuova posizione, aggiorna le informazioni sulla sua posizione in questo modo:
PUT /address/abc HTTP/1.1
Host: http://www.acmee.com
Content-Type: "application/json; charset=utf-8"
Content-Length: 109
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
{
"street": "Standford Ave",
"zip": "CA 94306",
"city": "Pablo Alto",
"country": "United States of America"
}
Con la semantica trasformazione-prima della sostituzione per il tipo di media non corrispondente tra la risorsa indirizzo esistente e quella nella richiesta, come descritto sopra, la risorsa indirizzo è ora aggiornata e ha l'effetto che su una successiva richiesta GET
sulla risorsa utente viene restituito il nuovo indirizzo per l'utente
GET /users/1234 HTTP/1.1
Host: http://www.acmee.com
Accept: application/hal+json; charset=utf-8
Accept-Encoding: gzip, deflate
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
ETag: "e0023aa4e"
{
"name": "Charlie Gold-Smith",
"age": 40,
"job_title": "Senior Software Developer",
"_links": {
"self": { "href": "/users/1234" },
"employee": { "href": "http://www.acmee.com" },
"curies": [{ "name": "ea", "href": "http://www.acmee.com/docs/rels/{rel}", templated": true}],
"ea:admin": [
"href": "/admin/2",
"title": "Admin"
]
},
"_embedded": {
"ea:address": {
"street": "Standford Ave",
"zip": "CA 94306",
"city": "Pablo Alto",
"country": "United States of America"
"_links": {
"self": { "href": "/address/abc" },
"google_maps": { "href": "http://maps.google.com/?ll=37.4241311,-122.1524475" }
}
}
}
}
Patching dei dati parziali
PATCH
è definito in RFC5789 e non fa direttamente parte delle specifiche HTTP di per sé. Un errore comune è che l' invio solo dei campi che dovrebbero essere parzialmente aggiornati è sufficiente all'interno di una richiesta PATCH
. La specifica pertanto afferma
Il metodo PATCH richiede che una serie di modifiche descritte nell'entità richiesta venga applicata alla risorsa identificata dall'URI della richiesta. Il set di modifiche è rappresentato in un formato chiamato "documento patch" identificato da un tipo di supporto.
Ciò significa che un client deve calcolare i passaggi necessari necessari per trasformare la risorsa dallo stato A allo stato B e inviare queste istruzioni al server.
Un popolare tipo di supporto basato su JSON per l'applicazione delle patch è JSON Patch .
Se l'età e il titolo di lavoro del nostro utente campione cambiano e deve essere aggiunto un campo aggiuntivo che rappresenta il reddito dell'utente, un aggiornamento parziale usando PATCH
usando la Patch JSON può assomigliare a questo:
PATCH /users/1234 HTTP/1.1
Host: http://www.acmee.com
Content-Type: application/json-patch+json; charset=utf-8
Content-Length: 188
Accept: application/json
If-Match: "e0023aa4e"
[
{ "op": "replace", "path": "/age", "value": 40 },
{ "op": "replace", "path": "/job_title", "value": "Senior Software Developer" },
{ "op": "add", "path": "/salery", "value": 63985.00 }
]
PATCH
può aggiornare più risorse contemporaneamente e richiede di applicare le modifiche atomicamente, il che significa che devono essere applicate tutte le modifiche o nessuna che apporta un carico di transazione sull'implementatore dell'API.
Un aggiornamento riuscito potrebbe restituire qualcosa di simile
HTTP/1.1 200 OK
Location: /users/1234
Content-Type: application/json
ETag: "df00eb258"
{
"name": "Charlie Smith",
"age": 40,
"job_title": "Senior Software Developer",
"salary": 63985.00
}
sebbene non sia limitato solo a 200 OK
codici di risposta 200 OK
.
Per evitare aggiornamenti intermedi (le modifiche effettuate tra il recupero precedente dello stato di rappresentazione e l'aggiornamento) devono essere utilizzate l'intestazione ETag
, If-Match
o If-Unmodified-Since
.
Gestione degli errori
La specifica su PATCH
consiglia la seguente gestione degli errori:
genere | Codice di errore |
---|---|
Documento patch malformato | 400 Bad Request |
Documento di patch non supportato | 415 Unsupported Media Type |
Richiesta non processabile, vale a dire se il resoure diventasse non valido applicando la patch | 422 Unprocessable Entity |
Risorsa non trovata | 404 Not Found |
Stato in conflitto, ovvero un rinominare (spostare) un campo che non esiste | 409 Conflict |
Modifica in conflitto, cioè se il client utilizza un'intestazione If-Match o If-Unmodified-Since che ha avuto esito negativo. Se non era disponibile alcuna precondizione, è necessario restituire il secondo codice di errore | 412 Precondition Failed o 409 Conflict |
Modifica simultanea, cioè se la richiesta deve essere applicata prima dell'accettazione, ulteriori richieste di PATCH | 409 Conflict |
Elimina una risorsa
Un altro uso comune delle API HTTP è quello di eliminare una risorsa esistente. Questo di solito dovrebbe essere fatto usando le richieste DELETE
.
Se la cancellazione ha avuto successo, il server dovrebbe restituire 200 OK
; un appropriato codice di errore se non lo fosse.
Se il nostro dipendente Charlie Smith ha lasciato l'azienda e ora vogliamo cancellare i suoi record, potrebbe essere simile a questo:
DELETE /employees/1/charlie-smith HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
'links': [
{
'uri': '/employees',
'rel': 'create',
'method': 'POST'
}
]
}
Elenca le risorse
L'ultimo uso comune delle API HTTP è ottenere un elenco di risorse esistenti sul server. Gli elenchi come questo dovrebbero essere ottenuti utilizzando le richieste GET
, poiché recuperano solo i dati.
Il server deve restituire 200 OK
se è in grado di fornire l'elenco o un codice di errore appropriato, in caso contrario.
Elencare i nostri dipendenti, quindi, potrebbe assomigliare a questo:
GET /employees HTTP/1.1
Host: example.com
HTTP/1.1 200 OK
Content-Type: application/json
{
'employees': [
{
'name': 'Charlie Smith',
'age': 39,
'job_title': 'Software Developer',
'salary': 63985.00
'links': [
{
'uri': '/employees/1/charlie-smith',
'rel': 'self',
'method': 'GET'
},
{
'uri': '/employees/1/charlie-smith',
'rel': 'delete',
'method': 'DELETE'
},
{
'uri': '/employees/1/charlie-smith',
'rel': 'edit',
'method': 'PATCH'
}
]
},
{
'name': 'Donna Prima',
'age': 30,
'job_title': 'QA Tester',
'salary': 77095.00
'links': [
{
'uri': '/employees/2/donna-prima',
'rel': 'self',
'method': 'GET'
},
{
'uri': '/employees/2/donna-prima',
'rel': 'delete',
'method': 'DELETE'
},
{
'uri': '/employees/2/donna-prima',
'rel': 'edit',
'method': 'PATCH'
}
]
}
],
'links': [
{
'uri': '/employees/new',
'rel': 'create',
'method': 'PUT'
}
]
}