s-max-age — similar to max-age, however it refers to a shared cache therefore only relevant to CDNs and other intermediary caches.

must-revalidate — instructs the client to resend request headers and receive confirmation that the resource has not changed.

proxy-revalidate — similar to must-revalidate, however specific to shared caches.

Example

\# Example caching response

HTTP/1.1 200 OK

Date: Wed, 06 Jul 2016 21:14:52 GMT

Expires: Wed, 06 Jul 2016 22:14:52 GMT

Cache-Control: private,max-age=14400,must-revalidate

Content-Type: application/json

Care should be taken when using caches, especially shared or public caches. In some cases it may be more prudent to use the no-cache directive to ensure that content is not cached outside your network. This does not rule out caching within your API layer. For more information, see section 1.12. Caching.

HTTP Cache Control standards can be found in Hypertext Transfer Protocol (HTTP/1.1): Caching RFC 7234 — IETF.

4.2.5. Expires — Recommended

When using Cache-Control you should include an Expires header in the response for backward compatibility.

4.2.6. ETag (Entity Tag) — Recommended

The ETag header is a concurrency control header, and when in a response it is a tag that the consuming application can use when making a subsequent request to a resource.

Note that pre-condition handling is not required, but should be considered where appropriate. Pre-condition control can be a complex topic so in some cases the complexity may eclipse the value.

Example

\# Response with ETag Header

\# Consuming application would send this ETag in an If-None-Match #request header

ETag: "686897696a7c876b7e"

4.3. Custom X-HTTP headers

X- notation headers have been deprecated and should not be used.

Deprecating the “X-” Prefix and Similar Constructs in Application Protocols RFC 6648 — IETF

This is because the X- name often became a standard, making the X-notation inaccurate (for example, x-gzip became gzip) and requiring support for both the X- and the non-X- notation. Common uses of the X- headers are examples such as the X-HTTP-Method-Override header or the X-Forwarded-For header.

Where an agency feels that a custom HTTP header is required that is not available within the current HTTP standard they can use a custom header without the X- prefix.

5. Appendix C — Example interface specification

Figures 5 to 8 illustrate examples of an agency API interface. The examples are:

Create customer

Get customer

Modify customer

Delete customer.

Following the figures is the interface specification written in Swagger and visualised via a Confluence plugin, however most API developer portal products will support importing OpenAPI specifications.

Figure 5: Example agency API — Create customer

Figure 6: Example agency API — Get customer details

Figure 7: Example agency API — Modify customer

Figure 8: Example agency API — Delete customer

The raw JSON, YAML and Swagger code is below. This is best viewed via the Swagger (OpenAPI) editor. Simply open the editor and paste the contents of the JSON, YAML and Swagger examples into the editor window.

JSON example

{

"swagger": "2.0",

"info": {

"version": "2.0.0",

"title": "Example Agency API",

"description": "A sample API specification demonstrating OpenAPI capabilities — this is for example purposes only",

"termsOfService": "https://developer.example.govt.nz/termsandconditions/",

"contact": {

"name": "Example Agency API team",

"email": "exampleteam@api.govt.nz",

"url": "https://agency.govt.nz"

}

},

"host": "api.example.govt.nz",

"basePath": "/v2",

"paths": {

"/customers/{customerId}": {

"get": {

"parameters": [

{

"name": "customerId",

"in": "path",

"description": "Unique ID of customer",

"required": true,

"type": "string"

}

],

"tags": [

"get customer details"

],

"description": "Returns details for a customer given a unique customer ID\\n",

"security": [

{

"AuthorizationCode": [

"customerRead"

]

}

],

"produces": [

"application/json"

],

"responses": {

"200": {

"description": "OK — Successful",

"schema": {

"$ref": "#/definitions/customerDetailsResponse"

}

},

"default": {

"description": "Error response",

"schema": {

"$ref": "#/definitions/errorModel"

}

}

}

},

"put": {

"tags": [

"modify customer"

],

"description": "Updates a customer’s details",

"consumes": [

"application/json"

],

"produces": [

"application/json"

],

"parameters": [

{

"name": "customerId",

"in": "path",

"description": "Unique ID of customer",

"required": true,

"type": "string"

},

{

"name": "body",

"in": "body",

"required": true,

"schema": {

"$ref": "#/definitions/customerRequestModel"

}

}

],

"responses": {

"200": {

"description": "Updated resource successfully"

},

"default": {

"description": "Error response",

"schema": {

"$ref": "#/definitions/errorModel"

}

}

},

"security": [

{

"AuthorizationCode": [

"customerWrite"

]

}

]

},

"delete": {

"tags": [

"delete customer"

],

"description": "Deletes an existing customer resource",

"consumes": [

"application/json"

],

"produces": [

"application/json"

],

"parameters": [

{

"name": "customerId",

"in": "path",

"description": "Unique ID of customer",

"required": true,

"type": "string"

}

],

"responses": {

"200": {

"description": "Deleted resource successfully"

},

"default": {

"description": "Error response",

"schema": {

"$ref": "#/definitions/errorModel"

}

}

},

"security": [

{

"AuthorizationCode": [

"customerDelete"

]

}

]

}

},

"/customers": {

"post": {

"tags": [

"create customer"

],

"description": "Creates a new customer. API will create a customer resource and, if successful, return a hyperlink to the created resource",

"consumes": [

"application/json"

],

"produces": [

"application/json"

],

"parameters": [

{

"name": "body",

"in": "body",

"required": true,

"schema": {

"$ref": "#/definitions/customerRequestModel"

}

}

],

"responses": {

"201": {

"description": "Created resource successfully",

"schema": {

"$ref": "#/definitions/_links"

}

},

"default": {

"description": "Error response",

"schema": {

"$ref": "#/definitions/errorModel"

}

}

},

"security": [

{

"AuthorizationCode": [

"customerCreate"

]

}

]

}

}

},

"securityDefinitions": {

"AuthorizationCode": {

"type": "oauth2",

"scopes": {

"customerRead": "Grants read access to a customer resource",

"customerWrite": "Grants write (update) access to an existing customer resource",

"customerCreate": "Grants access to create a new customer resource",

"customerDelete": "Grants access to delete an existing customer resource"

},

"flow": "accessCode",

"authorizationUrl": "https://idm.example.govt.nz/oauth/authorize",

"tokenUrl": "https://idm.example.govt.nz/oauth/access_token"

}

},

"definitions": {

"customerRequestModel": {

"type": "object",

"properties": {

"names": {

"type": "object",

"properties": {

"firstName": {

"type": "string",

"description": "Customers first name"

},

"middleName": {

"type": "string",

"description": "Customers middle name"

},

"lastName": {

"type": "string",

"description": "Customers last name"

},

"salutation": {

"type": "string",

"description": "Customers salutation — for example, Mr John Doe"

},

"title": {

"type": "string",

"description": "Customers title — for example, Ms, Mr, Mrs, Dr, and so on."

}

}

},

"addresses": {

"type": "array",

"description": "An array of addresses. Unpopulated properties or items will be returned as null JSON objects.",

"items": {

"properties": {

"addressType": {

"type": "string",

"description": "Address type — for example, Home, Business"

},

"address1": {

"type": "string",

"description": "First line of the address — for example, 2 something street"

},

"address2": {

"type": "string",

"description": "Second line of address — for example, Khandallah"

},

"address3": {

"type": "string",

"description": "Third line of address — for example, Wellington"

},