Accept: application/json,version=1.*

{

"people": [

{

"names": {

"firstName": "John",

"middleName": "Howard",

"lastName": "Doe",

"salutation": "Mr John Doe",

"title": "Mr"

}

},

{

"names": {

"firstName": "Mary",

"middleName": "Pauline",

"lastName": "Smith",

"salutation": "Ms Mary Smith",

"title": "Ms"

}

},

{

".....lots more people here.....": "..."

}

]

}

Example response

200 OK

Note that the API is unable to respond with headers such as Location as this request should be treated as asynchronous.

1.10. API version control

Learn more about the commonly-used types of versioning when developing an API.

1.10.1. API version control methods

There are 2 main API versioning methodologies commonly used. There are positives and negatives to both approaches and a large amount of debate over which is the most ‘RESTful’. Rather than stipulate a methodology to use in these guidelines, each methodology is described below in order of preference. Both, however, are acceptable. What is more important is that APIs are versioned and that there is an understanding of when and why to version an API.

1. Accept header versioning

This is usually considered the most RESTful way to version APIs because the resource path remains ‘pure’ and it is possible to provide more version flexibility for clients. It is, however, technically more difficult to implement and in many cases commercial API management / gateway products do not support or work well with this approach.

Header-based versioning should be performed using the Accept header where a consuming application requests an API version as defined in an Accept header. Wildcards (*) are used by the consuming application to indicate acceptance of the latest major or minor version of an API.

Example

#Get details for provider id 123435 – latest minor version of the API

GET https://api.example.govt.nz/providers/12345

Accept: application/json, version=1.*

Host: api.example.govt.nz

#Get details for provider id 123435 – version 1.1 of the API

GET https://api.example.govt.nz/providers/12345

Accept: application/json, version=1.1

Host: api.example.govt.nz

#Get details for provider id 123435 – latest version of the API

GET https://api.example.govt.nz/providers/12345

Accept: application/json, version=*

Host: api.example.govt.nz

The response should include the version of the API that responded to the client request in the ‘Content-Type’ header.

Example

Content-Type: application/json,version=1.2

2. URI (path) versioning

URL-based versioning is a viable alternative, as the version number in the URL should only change when major revisions have been made and the interface has changed substantially without backwards compatibility. For URL-based versioning the URI should include /vN with the major version (N) and v as a prefix. Agencies should not include minor version numbers when using version numbers in the API paths.

This is probably the easiest method to implement, but a number of REST purists feel that it compromises the URI and does not offer enough flexibility to consumers. If there is a requirement to support a large number of historical versions of APIs it can mean that there is complexity introduced with the number of URIs to maintain.

Example

#Query version of version 1 of the search API

GET https://api.example.govt.nz/customers/v1/search?first-name=John&last-name=Smith&page-size=10

#Query version 2 of the search API

GET https://api.example.govt.nz/customers/v2/search?first-name=John&last-name=Smith&page-size=10

The response should still indicate the version of the API that was called. This can be done as in the example above, using the Content-Type header or in the Location header, as the version in the path indicates the API that was called.

1.10.2. When to version

Simply put, an API should be versioned when a change is considered a breaking change. One of the benefits of an API is that, if it is well designed, there should be fewer breaking changes. In government however, there are likely to be situations where legislative changes enforce a new version of an API and deprecation of all previous versions.

1.10.2.1. Breaking changes

A change is a breaking change if any consuming application requires changes to work with the new version. In other words, the new version will not successfully process messages provided by existing consumers. A breaking change should be considered as a major version change, for example, 1.3 to 2.0.

Examples of breaking changes include:

the removal of any property from the response representation

the change of datatype for an existing property or a change from optional to required

the removal of any resource or HTTP Verb support

a change to the way errors are handled

any change to existing resource URIs.

1.10.2.2. Non-breaking changes

A change is a non-breaking change if any message that would have been processed by the previous version will be successfully processed by the new version (that is, backwards compatible). This will enable an existing consumer of the previous version to work with the new version without requiring modification. A non-breaking change should be considered as a minor version change, for example, 1.1 to 1.2.

Such changes include:

the addition of new properties to the JSON representation

the addition of new resources

the addition of support for new HTTP Verbs (new operations) on existing resources

support for new custom headers, for example, for request tracing.

1.10.3. Software configuration management

It is important to remember that version control is more than just versioning the resource. An API will inherently have associated code and artefacts. Consider what comprises an API and include these as a logical artefact stored and managed in a software configuration management (SCM) system.

It is a good idea to try and capture all components in a format that can be controlled by SCM. A good example of this is Unified Modeling Language (UML) diagrams — these cannot be version-controlled unless captured in a text-like format. For examples of textual UML modelling, see:

Web Sequence Diagrams

PlantText UML editor — PlantText

An API artefact should, where possible, comprise the following elements:

any API code

API specification (OpenAPI)

unit test scripts such as JUnit or Mocha

continuous integration support files such as grunt.js or Ant scripts.

1.11. Search

Search should be implemented using GET requests with filters provided as query string parameters.

Search can be used by API consumers to filter or sort information they want from an API.

For instance, ‘GET /groups/search?status=active’ would enable the consumer to filter the groups resource on status.

Alternatively, ‘GET /groups/search?status=active&sort=status,name’ enables the consumer to return active groups ordered by status and name. It can also be useful to allow the consumer to choose which fields they want back from the API, so they only receive the content they need in the API response.

Example

#Get a list of groups that are either active or inactive, sorted by

#name and status

GET https://api.example.govt.nz/groups/search?status=active,inactive&sort=name,status

{

"groups": [

{

"id": "0219c539-5885-4ab6-a55b-b0de7537c426",

"name": "API lovers",

"status": "active"

},

{

"id": "1219c539-5885-4ab6-a55b-b0de7537c427",

"name": "Developers",

"status": "active"

},

{

"id": "7219c539-5885-4ab6-a55b-b0de7537c42c",

"name": "Risk analysts",

"status": "active"

},

{

"id": "3219c539-5885-4ab6-a55b-b0de7537c42h",

"name": "Writers",

"status": "active"

},

{

"id": "g219c539-5885-4ab6-a55b-b0de7537c425",

"name": "Authors",

"status": "inactive"

}

],

"_links": [

{

"rel": "self",

"href": "https://api.example.govt.nz/groups?sort=status,name"

},

{

"rel": "API Lovers",

"href": "https://api.example.govt.nz/groups/0219c539-5885-4ab6-a55b-b0de7537c426"

},

{

"rel": "Developers",