KijiREST API Compatibility

ANithian edited this page Nov 13, 2013 · 1 revision

Introduction

KijiREST, much like other components of Kiji can contain changes to the interface that clients see and the input/output formats that clients use to read and write to REST. This does not make any guarantee on the code/internal APIs used to implement the endpoints as KijiREST is a server application rather than a library that is embedded inside a larger application.

The REST API consists of the following major components:

  • Endpoints
  • Query parameters (name/value pairs)
  • JSON response on all endpoints
  • Status codes of methods.
  • JSON input for POST. Three types of changes:
  1. Major Version
  2. Minor Version
  3. Patch Version Below is a description of what is guaranteed across different version changes.

Major Version

Anything goes. Here, endpoints can be renamed, added, removed. Query parameters can be added, dropped and request/response formats change. There is no requirement of compatibility for clients upgrading from a previous major version to the latest major version.

For example, if a server was running KijiREST 1.0.10 and is upgraded to 2.0.0, we expect that before deployment to production, all clients are upgraded/changed to conform to any input/output/interface changes that may have been made.

Minor Version

An administrator must be able to upgrade KijiREST from a previous to a new minor release without having to worry about current clients breaking. This means that any JSON that was accepted in the previous version must be accepted in the new version and any query parameters accepted in the previous version must be accepted in the new version. Note in both the cases of query parameters and JSON responses, data types for values may be upgraded/promoted but not downgraded. For example, if the "versions" parameter is currently interpreted as an integer but a new minor version interprets this as a long then this is compatible; however if this used to be a long but now needs to be an integer, this would be incompatible and could only happen in a major release.

Query Parameters

It’s okay to introduce new query parameters for added functionality. If this new query parameter is introduced to deprecate another query parameter, then please note this in the documentation/release notes as there is no way to annotate this (to my knowledge). No query parameters may be removed when releasing a new minor version. The deprecation is there to indicate that the next major version will remove said parameters. Once a client upgrades from an old minor version to a newer minor version (and starts using new functionality) there is no guarantees of compatibility upon downgrading without changes.

JSON Input/Output

Similar to query parameters, it’s okay to introduce new elements into the JSON input/output as long as the presence/absence of these new elements don’t break older clients. For example, the lowest level “cell” is represented as {“timestamp”:, “value”:}. The introduction of the “writer_schema” element would seem like an incompatible change; however, the absence of its presence on writes could cause an error because of how cells are written to Kiji relying on this element.

Similar to type changes to elements, all type changes between minor versions must not break clients who may be expecting an older version of the JSON.

Patch Version

This is the most restrictive. Only bug fixes are allowed. Code changes within the KijiREST codebase are perfectly okay and for now, there are no contracts with external customers around the methods used to actually implement functionality. Clients must be able to upgrade/downgrade KijiREST between patch versions and require no changes by the clients.

If the bug fix requires a change in interpretation of a query parameter that breaks backwards compatibility OR JSON input/output that breaks backwards compatibility, then this requires an increment in the minor release.

Examples of something that would be valid as a patch release:

  • Fixing a memory leak
  • Fixing a corner case on read/write that causes an exception.
  • Other issues that are not client facing but improve the functionality of the server (efficiency/caching improvements etc).

Status Codes of Methods

Currently, we adhere to the following:

  • 200 - OK. This means that the server properly responded to the request with a useful response.
  • 404 - Not Found. This means that the resource requested was not found.
  • 500 - Internal Server - This means that there was an exception during processing of the request.
  • 400 - Bad Request - This means that the request specified was invalid.
  • 403 - Forbidden - This means that you tried to access a resource not eligible to be requested (i.e. an instance that is not listed in the set of accessible instances).

If any of the requests throw an exception, those should contain a JSON body with a reason for the exception. Under those circumstances, a change to the JSON body shall constitute an API change. However, because our current implementation of KijiREST relies on DropWizard and its exception handling is less than perfect, we reserve the right to change the body of any exceptions not listed above OR whose body is HTML as that is considered a bug and may be changed in a minor (or possibly patch) version to JSON. Therefore, please don’t code clients to parse exceptions messages from KijiREST that are not JSON for they may change as we discover better ways to handle these exceptions.

Furthermore, a change in the status code of an already established exception is considered an API change. The version increment depends on the change. Examples:

  • If we decide that an instance not listed in the accessible list of instances now throws a 404 (Not Found) instead of a 403 (Forbidden), this is considered an API change and can only happen in a major version. This is because a client using 1.0 should work with a server running 1.1 and this change would break backwards compatibility with the 1.0 client who expect a 403 instead of the new 404.
  • If we decide that we want to add an extra JSON block in the response body showing more details (say a more detailed stack trace) then this can be done in a minor release since older clients can still work with the newer server.
  • If we fix a bug where an exception message throws a 500 with an HTML body and determine that this is truly a 500 error but we properly place a JSON body in the response, then this is considered a bug fix and will go out in a patch release. This is because we ask clients explicitly to not code against non-JSON bodies in an exception.
  • However, if the above situation happened and we decide that it’s really a 400 Bad Request, then this change would go out in the next minor release since older clients expecting a 500 now would have to change to possibly expect a 400 in that situation.

Wire Compatibility

Currently, all input/output is plain text JSON sent via HTTP. Given that KijREST doesn’t yet conform to any best practices around requesting content of a different type (i.e. requiring the specification of the accept header in the request), changes to the wire protocol must be done carefully. If a best practice is adopted (say we rely on sending the “accept” header on the GET request), the following are okay:

  • Release this as a new major version if we require the specification of a return type and the absence of this is an error. This change would force all clients to specify this return type specification.
  • Release this as a new minor version if we will handle a specification of a return type and the absence of this will default to plain text JSON. Clients who know about this new change can specify this return type; however, clients who didn’t upgrade can still operate with KijiREST because the default is JSON. The next major version though may remove this default forcing all users to specify the return type. It is not okay to release such a change under a new patch version for an administrator who upgrades from 1.0.1 to 1.0.2 cannot safely downgrade back to 1.0.2 because this might require client changes.

References

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.