However, PUT can also be used to create a resource in the case where the resource ID is chosen by the consumer instead of by the API itself: where PUT is to a URI that contains the value of a non-existent resource ID. Again, the request body contains a resource representation. This method of creation should be avoided, if possible, or used sparingly. If consumer-defined resource IDs are required, use POST to create the new resource and provide the consumer-defined ID in the body representation (see section 3.2. POST).

On a successful update, PUT returns HTTP status 200 (or 204 if not returning any content in the body). If using PUT to create, PUT returns HTTP status 201 on successful creation. Content in the body in the response is optional. It is not necessary to return a link via a Location header in the creation case since the consumer already knows the resource ID, having set it themselves.

PUT is not a safe operation — it modifies (or creates) state on the server, but it is idempotent. That is, if you create or update a resource using PUT and then make that same call again, the resource is still there and still has the same state as it did with the first call. However, were the PUT call to increment a counter within the resource, the call is no longer idempotent. Sometimes this is necessary behaviour, and it may be enough to document that the call is not idempotent. However, it’s recommended to keep PUT requests idempotent. It is strongly recommended to use POST for non-idempotent requests.

It is good practice to perform a GET on a resource before you perform a PUT. This means that the consuming application has the latest representation of that resource. PUT should contain the entire resource content in the message body. By performing a GET prior to the PUT the consuming application can re-send the results of the GET with any modifications.

When using a resource response cache, any PUT to a resource should invalidate that cache or re-populate the cache with the updated resource.

3.3.1. Examples

Example

\# Get a resource

GET https://api.example.govt.nz/passengers/12345/1w3r4y6u

\# The response can be cached in a response cache with a cache key of the resource — for example, cachekey\_\_12345\_1w3r4y6u

\# Response Body

{

"id": "1w3r4y6u",

"passenger_name": "SMITH/NICOLAS",

"pnr_number": "CG4X7U",

"travel_class": "business",

"seat": "74J",

"auxiliary_fields": [

{

"label": "Terminal",

"value": "T1"

},

{

"label": "Departure",

"value": "30OCT 19:05"

}

],

"secondary_fields": [

{

"label": "Boarding",

"value": "18:30"

},

{

"label": "Gate",

"value": "D57"

},

{

"label": "Seat",

"value": "74J"

},

{

"label": "Sec.Nr.",

"value": "003"

}

],

"flight_info": {

"flight_number": "KL0642",

"departure_airport": {

"airport_code": "JFK",

"city": "New York",

"terminal": "T1",

"gate": "D57"

},

"arrival_airport": {

"airport_code": "AMS",

"city": "Amsterdam"

},

"flight_schedule": {

"departure_time": "2016-01-02T19:05",

"arrival_time": "2016-01-05T17:30"

}

}

}

Example

\# Put to a resource (update) changing the seat number

PUT https://api.example.govt.nz/passengers/12345/flights/1w3r4y6u

#The api invalidates cache object with key cachekey\_\_12345\_1w3r4y6u

{

"id": "1w3r4y6u",

"passenger_name": "SMITH/NICOLAS",

"pnr_number": "CG4X7U",

"travel_class": "business",

"seat": "10J",

"auxiliary_fields": [

{

"label": "Terminal",

"value": "T2"

},

{

"label": "Departure",

"value": "30OCT 19:05"

}

],

"secondary_fields": [

{

"label": "Boarding",

"value": "18:30"

},

{

"label": "Gate",

"value": "D57"

},

{

"label": "Seat",

"value": "10J"

},

{

"label": "Sec.Nr.",

"value": "003"

}

],

"flight_info": {

"flight_number": "KL0642",

"departure_airport": {

"airport_code": "JFK",

"city": "New York",

"terminal": "T1",

"gate": "D57"

},

"arrival_airport": {

"airport_code": "AMS",

"city": "Amsterdam"

},

"flight_schedule": {

"departure_time": "2016-01-02T19:05",

"arrival_time": "2016-01-05T17:30"

}

}

}

\# Response that update was successful

HTTP/1.1 204 No Content

Content-Location: /passengers/12345/flights/1w3r4y6u

3.4. DELETE

DELETE is used to delete a resource item.

DELETE is only used to delete a resource identified by a URI.

On successful deletion, DELETE returns an HTTP status 200 (OK) along with a response body, and optionally the representation of the deleted item, or a wrapped response. Alternatively, DELETE can return HTTP status 204 (NO CONTENT) with no response body.

DELETE operations are idempotent. If you DELETE a resource, it is removed. Repeatedly calling DELETE on that resource ends up as the same result — the resource is gone. However, calling DELETE on a resource a second time will often return a 404 (NOT FOUND) since it was already removed and therefore is no longer findable. This, in some opinion, makes DELETE operations no longer idempotent, but the end state of the resource is the same. Returning a 404 is acceptable and communicates accurately the status of the call. If calling DELETE were to decrement a counter (within the resource), the DELETE call is no longer idempotent.

3.4.1. Examples

Example

#Delete a resource

DELETE https://api.example.govt.nz/passengers/12345/flights/1w3r4y6u

Example

#Response

HTTP/1.1 204 No Content

Content-Location: /passengers/12345/flights/1w3r4y6u

3.5. OPTIONS

OPTIONS is used to retrieve information about what the consumer is allowed to do with the resource.

3.6. Other

PATCH is a valid HTTP verb but is still in draft and its use is discouraged due to complexity. An exception to this might be where an agency-adopted standard, such as Restful API — FHIR , supports the use of PATCH.

HEAD is used to retrieve metadata about a resource, such as when it was last updated or the associated response headers. The response to a HEAD request must not contain a body. If a response body is returned it must be ignored.

4. Appendix B — HTTP headers

4.1. Request headers — Required

Request headers are supplied by the consuming application and must include the following elements:

Accept

Content-Type

Authorization.

Header definitions can be found in Header Field Definitions: RFC 2616 — W3C.

4.1.1. Accept — Required

An Accept header is required to indicate what format the consuming application wants the information to be returned as (for example, JSON or XML). It is preferable for the consuming application to specify the response content type that they expect, however it is acceptable to use the ‘q’ parameter to specify the quality of support.

Example

#Accept JSON and latest version

Accept: application/json,version=*

#Prefer JSON, Accept XML and latest version 1 release

Accept: application/json;q=1.0,application/xml;q=0.8,version=1.*

#Accept XML only and version 1.2 only

Accept: application/xml;q=1.0,application/json;q=0.0,version=1.2

If the client has specified via the Accept header that it does not support any formats provided by the API, the server should return an HTTP 406 (Not Acceptable) response. The response should also include a Link header with a link to documentation or help on supported formats. The body of the representation should include an error message in human readable plain text or HTML.

Example response

\# Response that indicates the request failed due to the client not

\# supporting any response formats provided by the API

HTTP/1.1 406 Not Acceptable

Content-Type: text/plain

This API does not support any of the requested content types specified in the HTTP Accept header. Please see [http://www.example.com/api/documentation/widgetservice](http://www.example.com/api/documentation/widgetservice) for details on the supported content types.

The Accept header is required, however the ‘version’ and ‘q’ are recommended as this will depend on a provider’s implementation and in some cases technology choice.

4.1.2. Content-Type — Required