SQR-092
Draft IVOA JSON encoding#
Abstract
Proposes a JSON network protocol encoding for IVOA web service protocols.
Warning
This document is not an IVOA standard and is not complete. It is an experiment intended as input to ongoing IVOA discussions about future revisions to IVOA standards. The document is written as if it were an IVOA standard to save effort if parts of it can be cut and pasted into future documents, but it is not endorsed by the IVOA and is not part of any IVOA protocol.
See also
- SQR-91: Draft IVOA web service standards framework
The draft protocol structure for IVOA web services. This specifies what should be included in a network protocol specification such as this one.
- SQR-093: Draft IVOA SODA web service specification
An example network protocol specification for a simple SODA cutout service using this framework.
Overview#
The network protocol encoding portion of an IVOA web service standard specifies how to send requests, receive responses, and encode data types. This document specifies an encoding built on HTTP and JSON.
All requests are HTTP requests. The version of the HTTP protocol is unspecified; any version that is compatible with standard HTTP verbs and headers may be used. However, implementations of this network encoding should normally provide an HTTP/1.1 implementation, at least as a fallback, since support for newer versions of the HTTP protocol is still limited.
Clients and servers are expected to conform to the normal requirements of the HTTP protocol. Only the portions that are specific to IVOA web protocols are specified here.
Data type encoding#
This network protocol provides two data type encodings: an encoding into JSON that should be used for requests via POST
, PUT
, or PATCH
and all structured responses; and an encoding into query parameters that should be used for GET
requests.
The JSON encoding is the default unless the web service specifies that GET
is permitted for a given operation.
JSON encoding#
This description of encodings uses the terminology of RFC 8259.
- object
Encode as a JSON object.
- null
Encode as the JSON literal
null
.- string
Encode as a JSON string.
- uri
Encode as a JSON string.
- integer
Encode as a JSON number without a fractional part or exponent.
- float
Encode all values other than positive infinity, negative infinity, and NaN as a JSON number. Encode positive infinity as the JSON string
"+Inf"
. Encode negative infinity as the JSON string"-Inf"
. Encode NaN as the JSON string"NaN"
.- boolean
Encode as the JSON literal
true
orfalse
.- enum
Encode as a JSON string.
- timestamp
Encode as an ISO 8601 string in the extended format. Use the calendar date format and include all components of the date. More than four digits are permitted for the year to specify dates after 9999 CE; however, these may not be supported in all implementations. Include at least hours, minutes, and seconds in the time. Milliseconds, if present, are encoded as a fractional part after the seconds using U+002E (
.
) as the decimal mark. For example,2024-08-23T14:42:47.043Z
.- duration
Encode the number of seconds in the duration as a JSON number.
- list
Encode as a JSON array. Object labels whose value type is a list must use the plural form of the label.
Query encoding#
The query encoding is used for GET
requests.
It does not support objects as values, and therefore requests whose input contains such types cannot be sent via GET
.
Web service specifications should choose which operations allow GET
with this in mind.
The encoding described below is for the value portion of the query parameter. The entire query parameter, including the label, is then encoded following the rules for query parameters in RFC 3986. Note that this may involve additional percent-encoding of special characters and characters outside of the ASCII character set.
- null
Do not include the label or value if the value is null.
- string
Encode as a UTF-8 string.
- uri
Encode as a UTF-8 string.
- integer
Encode as a UTF-8 string using the normal representation of an integer and the base digit code points (U+0030 through U+0039). Do not use any digit grouping marks. Negative integers are prefixed with U+002D.
- float
Encode as a UTF-8 string using the normal representation of a floating point number. Use U+002E as the decimal point and do not use any digit grouping marks. Exponents can be introduced with either
e
(U+0065) orE
(U+0045). Use U+002D to mark negative numbers. Encode positive infinity as the string+Inf
. Encode negative infinity as the string-Inf
. Encode NaN as the stringNaN
.- boolean
Encode as the string
true
or the stringfalse
.- enum
Encode as a UTF-8 string.
- timestamp
Encode as an ISO 8601 string in the extended format. Use the calendar date format and include all components of the date. More than four digits are permitted for the year to specify dates after 9999 CE; however, these may not be supported in all implementations. Include at least hours, minutes, and seconds in the time. Milliseconds, if present, are encoded as a fractional part after the seconds using U+002E (
.
) as the decimal mark. The encoded timestamp must end inZ
and must not include time zone offset information in any other format. For example,2024-08-23T14:42:47.043Z
.- duration
Encode the number of seconds in the duration as a UTF-8 string. Milliseconds, if present, are encoded as a fractional part after the seconds using U+002E (
.
) as the decimal mark.- list
Repeat the query parameter for each value, encoding each value following the regular rules for its data type.
Requests#
All client requests are HTTP requests.
Verbs#
The HTTP verb is mostly determined by the type of the operation. When a web service supports this network protocol, it must choose the appropriate verb in several cases discussed in detail below.
- query
POST
by default. The web service specification can also allowGET
, but should keep in mind the constraints discussed in Query encoding.- create
PUT
by default. In some cases,POST
is more appropriate. The web service specification can select either.- modify
PATCH
. The web service may also allowPUT
for complete replacement of the object.- delete
DELETE
.- action
POST
.
In all cases except GET
and DELETE
, the client must provide a body in JSON format, consisting of an encoding of the request object described in the web service specification.
The client must send the Content-Type: application/json
header to indicate that this request body is in JSON format.
Content negotiation#
When making a request for an operation that responds with data rather than a protocol object, the client can request the format of that object by using HTTP content negotiation.
For example, for an operation that returns an image, the client may wish that image in image/jpeg
format instead of application/fits
.
To do this, the client should send an HTTP Accept
header with its content preferences following the standard Accept
header syntax.
The server may reply with data in any of the formats the client indicates it accepts, but should prefer a format with a higher weight over a format with a lower weight if it knows how to produce either format.
The server may ignore this preference and return the easiest format to generate if it is under excessive load or otherwise needs to limit the amount of work that it does in response to the request.
If none of the MIME types listed in the Accept
header are supported by the server, the server should reply with an HTTP 406 error rather than a default format.
The body of that error should include a list of MIME types that the server is able to generate as part of the JSON-encoded error message.
If the server supports content negotiation and the client sent the Accept
header, the server must include a Vary
header in the response, specifying the headers that it used in its decision.
Responses#
The response from the server uses standard HTTP response codes.
Successful responses#
A successful response is indicated by a 2xx response code. Normally this will be 200, but 201 is appropriate after create operations, and 204 should be used when there is no accompanying response body, such as in response to a delete operation. Servers should choose a 2xx response approrpriate to the nature of the operation and response.
The web service specification will describe whether a response is a structured response encoded according to this document or a data response.
Structured responses following the encoding rules in this document must include Content-Type: application/json
in the response headers.
Data responses must include a Content-Type
header with an appropriate MIME type describing the format of the response.
For example, responses that return a VOTable in XML format must include Content-Type: application/x-votable+xml
.
Redirect responses#
The response may be an appropriate 3xx redirect response code for the type of request (, in which case the client should retrieve the location of the response from the Location
header and make a new GET
request to the provided URL.
Servers should normally use the 303 response code for this purpose, but clients should support any of 301, 302, 303, 307, or 308.
Error responses#
Errors in performing the operation must result in a 4xx or 5xx HTTP response code appropriate to the nature of the error.
A 4xx response code should be used when the client’s request is invalid for some reason. Using 422 as the HTTP response code for requests that do not pass input validation is recommended, since that makes it easier to distinguish protocol errors from semantic errors in the request. A 5xx response code should be used for apparently valid requests that cannot be handled due to some server problem. For client or server errors without a more specific assigned HTTP response code, use 400 or 500, respectively.
The server should attempt to include a structured error message as described in SQR-091 as the body of an error response whenever possible.
If this is possible, the error response must include the header Content-Type: application/json
, as with any other structured response.
Clients must support appropriate error reporting using only the information in the HTTP status code and fall back on that behavior if there is no structured error body, if the MIME type of the response is not application/json
, or if the error body is in an unknown format.
HTTP errors are frequently generated by other intermediate components outside of the web service, and those components will generally not follow IVOA conventions.
Web service specifications#
Web service specifications that support this network encoding must include an OpenAPI 3.0 schema for the web service as a supplemental part of the specification.
Web service specifications must also choose the HTTP verbs following the rules in Requests, and specify which operations are supported via GET
.
This information must be included in the schema, and should also be included in the body of the standard since implementors may miss it in the schema.