Skip to content

Latest commit

 

History

History
275 lines (213 loc) · 8.67 KB

3-JSON-Conventions.md

File metadata and controls

275 lines (213 loc) · 8.67 KB

RESTful Best Practices

3.1 Casing

APIs MUST use lowerCamelCase for all field names in the request, response, and documentation.  All field values that are enumerations MUST also be lowerCamelCase.

The vast majority of javascript developers use camelCase as their API standard, as do many other languages. Since JSON is serialized javascript, we prefer to use the common convention in that language. Additionally, we should design our APIs to be used directly from UIs - using the same casing standards as most javascript UI frameworks use eases that adoption.

Casing Examples

Instead of... Use lowerCamelCase!

alllowercase: foofieldname

UpperCamelCase: FooFieldName

snake_case: foo_field_name

SCREAMING_SNAKE: FOO_FIELD_NAME

kebab-case: foo-field-name

lowerCamelCase: fooFieldName
orderID orderId
pricePaidUSD pricePaidUsd
HTMLButton htmlButton

3.2 Data Types

3.2.1 Date and Times

APIs MUST use ISO-8601 for dates, dates without times, and date with times per RFC3339, UNLESS otherwise specified by a public RFC that an alternate standard must be used for a particular HTTP header value. For example: If-Unmodified-Since requires RFC822, so that format should be used for that header.

  • Some HTTP headers (ex: If-Unmodified-Since) may require the use of a specific format (ex. RFC822 Specification for ARPA Internet Text Messages §5 Date and Time). The requirement to use ISO-8601 and comply with RFC3339 is nullified in cases where a conflicting ratified public RFC standard exists.

Timestamps and timezones are complicated. Use international standards and best practices. The ISO-8601 standard has broad library support and history.

APIs SHOULD use and store UTC representations of date-times and timestamps.

  • When working with date-times, prefer UTC representations in your API over local timezones, and convert to user-preferred timezones separately.

Timezones are complex, and using local times for a global company is tricky. Where representing a fixed instant in time, prefer using a UTC representation.  

APIs **SHOULD **use ISO-8601 for time durations and intervals.

Many ISO‌-8601 parsing libraries will treat 24H and 1D as the same. Do not rely on the specific duration string provided as a means to convey further semantic information.

If your logic requires treating 24 hours differently then 1 day, it is unlikely you are modeling an interval and should use a different data structure to convey the differences in those values to your API consumer.

Date and Time Examples

Instead of these timestamps: Prefer ISO-8601 UTC:

Unix Timestamp: 1529941649

.NET Ticks: 636655384490000000

RFC1123: Mon, 25 Jun 2018 15:47:29 GMT

Or  any other way to represent a date-time.

2018-06-25T15:47:29Z

3.2.2 Identifiers

Identifiers **MUST **always be strings.

You don't know what your ID space will be in the future, or how big it should be. Use a string.

Identifiers SHOULD NOT be sequential integers.

Identifier Examples

Instead of integer Ids: Use strings or UUIDs:

"id": 1234

"id": 5

"id": 68583854

"id": "1234"

or better, use a UUID or other random string:

"id": "26yv0qzk7mv7vs5tq6qjy040af"

3.2.3 Numbers

JSON numbers SHOULD NOT be used except when representing small integer values.

Due to differences in serializers in many languages, there are often interoperability issues between serializers. Using strings for numbers also allows for significantly more precision when using decimal values, as JSON numbers are floating-point based, not decimals.

3.2.4 Enumerations

Enumeration values MUST be lowerCamelCase.

3.3 Reserved Field Names

APIs MAY include the below fields where appropriate. When an API provides these fields, they MUST be used consistently with the following semantics: 

  • id - the unique server created id of the resource. MUST be a string.
  • key - the client provided unique identifier for the resource. MUST be a string.
  • createdBy - the principal that created the resource. MUST be a string.
  • createdAt - the timestamp the resource was created. MUST be an ISO-8601 timestamp.
  • modifiedBy - the last principal to modify the resource. if no modifications have been made, this should be the createdBy principal. MUST be a string.
  • modifiedAt - the timestamp the resource was last modified. if no modifications have been made, this should be the createdAt timestamp. MUST be an ISO-8601 timestamp.

Common field naming promotes consistency in common fields that are commonly present across APIs.

We're not saying you need to have these fields, but they're a good idea in many cases. If you do have these fields, you MUST follow the above guidance.

Examples

Reserved field names

{
  "id": "4990a90a-acb5-416b-b3a3-69a71fb4c138",
  "key": "my-identifier",
  "createdBy": "asdafsdf",
  "createdAt": "{ISO-8601}",
  "modifiedBy": "asdafsdf",
  "modifiedAt": "{ISO-8601}",
  ...
}