HTTP JSON API Design Specification

Preface

More and more Web applications are interacting with JSON as a data exchange format for APIs. The goal of this document is to keep the design style of the HTTP JSON API consistent and easy to understand and maintain. A good API should be able to consistently provide stable, easy-to-use, trusted services throughout its lifecycle and smoothly disappear at the end of its lifecycle.

Note: RESTful API is a mature API design theory for Web applications. This article does not introduce RESTful API too much. In the real world of fast growing and changing business applications, using the RESTful API requires higher costs and higher requirements for back-end developers. We use this lightweight HTTP JSON API design more.

Appointment

In this document, the keyword used will be in Chinese + brackets containing the keyword in English: Must [MUST]. The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are interpreted as described in RFC 2119.

JSON data type

JSON (JavaScript Object Notation) is a lightweight, text-based, language-independent data exchange format. It includes four basic data types and two structural data types, a total of six data types.

Basic data types

  • String represents a string.
  • Number s can represent integers and floating-point numbers.
  • Boolean can be true or false.
  • Null is often used to represent empty objects.

"True" and "true", which represent different data types. Do not quote [MUST NOT] with double quotes at both ends when outputting data of non-string type, otherwise undesirable consequences may occur (e.g., if the result of "false" is true). Other error-prone examples are 0 and 0.

Structural data types

  • Objects are an unordered collection that maintains data as key-value pairs. An Object contains zero to more than one name/value of data, separated by commas (,). The name is of type String and the value can be any type of data. [MUST NOT] must not be followed by a delimiter comma after the last element of the Object, otherwise parsing errors may occur.
  • Array is an ordered collection of values separated by commas (,).

Agreement

Use HTTP or HTTPS protocol.

URL Specification

URLs represent the uniqueness and permanence of the API provided, and before that we should [SHOULD] design reasonable URLs:

MUST spell URL s in all lowercase letters

// good
http://www.example.com/api/v1/users?orderby=name
// bad
http://www.example.com/API/V1/users?orderBy=name

Must [MUST] use dash -.

// good
http://www.example.com/api/v1/user-info
// bad
http://www.example.com/api/v1/user_info

Destructive behavior (create, delete, update) must use the POST method [MUST]

// good
POST http://www.example.com/api/v1/user/delete
// bad
GET http://www.example.com/api/v1/user/detete?id=123

Recommend [RECOMMENDED] to use easy-to-understand English words

// good
POST http://www.example.com/api/v1/user/list
// bad
GET http://www.example.com/api/v1/user/operate

HTTP response header

status

The status of the http response must be (MUST) 200. JSON data is typically accessed through an XMLHttpRequest object and processed through javascript. Returning an error status code may result in the error not being responded to and the data not being processed.

Reference resources: List_of_HTTP_status_codes

Content-Type

The Content-Type field defines the type of response body. In general, browsers handle content correctly based on that type. The Content-Type recommendation (RECOMMENDED) is set to "text/javascript" or "text/plain" in response to the transfer of JSON data. Avoid (MUST NOT) setting Context-Type to text/html, otherwise it may cause security problems.

Character sets can be specified in Content-Type. Usually a character set needs to be explicitly specified (SHOULD). If the data is requested through an XMLHTTPRequest and the character encoding is UTF-8, the character set may not be specified.

Content-Type example

text/javascript;charset=UTF-8

HTTP Response Body

The returned data is contained in the body of the HTTP response. The data MUST be a JSON Object. The Object may contain three fields: code, msg, data.

{
    code: 200,
    msg: 'success',
    data: {
        xxx: '123'
    }
}

code

The code field is designed as a business-defined status code and must be a JSON Number integer of at least 0 to represent the status of the request. This field cannot be omitted (SHOULD NOT).

Whether or not to customize the business status code in the API is highly controversial because the Http request itself already has a complete status code and a set of status codes can be visually redefined. However, in the actual development, there may be different results and processing methods due to the user's non-logon and expired logon, so the code field must be present in [MUST].

The definition of status codes should also have a set of specifications, such as simple classification according to user-related, authorization-related, business-related:

// Authorization-related
1001: No access
1002: access_token Be overdue
1003: unique_token invalid
...

// User-related
2001: Not logged in
2002: User Information Error
2003: user does not exist

// Business 1
3001: Business 1 XXX
3002: Business 1 XXX

// ...

msg

The msg field, usually [SHOULD] is a JSON String or JSON Object, which indicates what the service side wants to say about this request in addition to the request status so that the client can get more information for subsequent processing. This field is optional [OPTIONAL]. In the following two examples, information from the msg field can be used for subsequent processing of client programs, but the granularity and processing will vary.

Simple msg:

{
    "code": 1,
    "msg": "Parameter error"
}

msg with more information:

{
    "code": 1,
    "msg": {
        "text": "Parameter error",
        "parameters": {
            "ticket": "ticket Invalid parameter"
        }
    }
}

data

The data field can be of any JSON type and represents the data body returned by the request. This field is optional [OPTIONAL]. The data body data contains data that makes sense when the request succeeds.

Return data for a name request:

{
    "code": 200,
    "data": "John"
}

Return data from a query for user information request:

{
    "code": 200,
    "data": {
        "username": "John",
        "age": "31",
        "gender": "male"
    }
}

Return data from a request to query user list information:

{
    "code": 200,
    "data": [
        {
            "username": "John",
            "age": "31",
            "gender": "male"
        },
        {
            "username": "Lily",
            "age": "28",
            "gender": "female"
        }
    ]
}

Data Scene

This chapter defines a common standard data format for common data scenarios for data transmission and use.

Variable data formats must be [MUST] a JSON Object, where [MUST] must contain both e-type and data attributes. The e-type attribute identifies the data type for easy data parsing. The data property contains the adapted data. Variable data can contain additional attributes that identify additional extended information about the data.

The e-type property of the flexible data format defines the table value. The e-type attribute can be used to extend other attribute values by the user. Extended attribute values must be named [MUST] with the project abbreviation-name, such as "fc-list" for autonomous resolution.

Date type

The date type is not a JSON data type. For date types, we must use a JSON String to represent [MUST]. To make dates easier to display and parse, we should [SHOULD], follow RFC 3339, use a format that is more Internet-friendly for dates.

Date display format

Format for displaying dates to front-end or back-end:

// General date format
2018-12-6 11:21:08

// Timestamp format (10-bit seconds)
1544066565

// Example
{
  code: 0,
  msg: 'success',
  data: '2018-12-6 11:21:08'
}

Record Item

Record items represent a row in a two-dimensional table and are often used to represent attributes that are abstract for a specific transaction. Standard record item data must be [MUST] a JSON Object, and the primary key name of the record item must be [MUST] an'id'.

Standard Record Item

{
  code: 0,
  msg: 'success',
  data: {
    "id": 1,
    "name": "John",
    "sex": "male",
    "age": 31
  }
}

Flexible Record Item

{
  code: 0,
  msg: 'success',
  data: [
    {
      label: 'Record ID',
      value: 1,
      type: 'number'
    },
    {
      label: 'User Name',
      value: 'John',
      type: 'string'
    },
    {
      label: 'User gender',
      value: 'male',
    },
    {
      lable: 'User Age',
      value: 31
    }
  ]
}

Two-dimensional table

The two-dimensional table type, identified as table, is the main data structure of the relationship model. The two-dimensional table structure has a flexible data format. Standard two-dimensional table data must be expressed as one-dimensional JSON Array, where each item is a JSON Object and represents a record. Each member of the JSON Object represents a field. The primary key name for each record must be [MUST] id.

In standard two-dimensional tables, field names are transferred in each record, resulting in additional data transfer. This problem will become more prominent as the number of records increases. To reduce the amount of data transferred, the flexible format uses two-dimensional JSON Array to transfer data, and the extended field properties are used for field descriptions. The fields field is JSON Array.

Standard 2-D Table

{
  code: 0,
  msg: 'success',
  data: [
    {
        "id": 1,
        "name": "John",
        "sex": "male",
        "age": 31
    },
    {
        "id": 2,
        "name": "Lily",
        "sex": "female",
        "age": 28
    }
  ]
}

Variable 2-D Table

{
  code: 0,
  msg: 'success',
  data: {
    "e-type": "table",
    "fields": ["id", "name", "sex", "age"],
    "data": [
        [1, "John", "male", 31],
        [2, "Lily", "female", 28]
    ]
  }
}

Key-Value Pairs

Represents key/value pairs in a JSON Object:

  • The attribute name of the key must be [MUST] as name, the use of key or k is prohibited for [MUST NOT]
  • The attribute name of a value must be [MUST] as value, and the use of v by [MUST NOT] is prohibited.
  • It is possible to extend the attribute name label to [MAY], generally the same as the name value.

Simple key/value

{
  code: 0,
  msg: 'success',
  data: {
    "name": "John",
    "value": 1,
    "lable": "John" // Optional
  }
}

Ordered Set

An ordered set of keys/values represents the abstraction and classification of a transaction or logical type. Common scenarios include a collection of radio check boxes, drop-down menus, and so on.

A standard ordered set of keys/values is a JSON Array, and each item in the set is a JSON Object. Item MUST contain name and value attributes. [MAY] can decorate each item's special information with other attributes, such as selected.

{
  code: 0,
  msg: 'success',
  data: [
    {
        "name": "Dissatisfied",
        "value": 0,
        "selected": true
    },
    {
        "name": "Satisfied",
        "value": 1
    },
    {
        "name": "Very satisfied",
        "value": 2,
        "selected": true
    }
  ]
}

Data Page

Data pages are a common form of data for list data and may be retrieved by querying or paging. Data pages are packages of two-dimensional table data that contain more information about the list data itself.

The data page must be [MUST] a JSON Object with the attribute [MUST] must contain as data. Data is a two-dimensional table. A data page can include optional [OPTIONAL] attributes that represent information for the current data page. The following table lists the optional properties of a data page.

Parameters/Attributes

  • pageNumber{Number} - Current page number, count must be [MUST] an integer not less than 1, starting from 1. Usually abbreviated as: pn
  • pageSize{Number} - Number of bars per page must be greater than 0 [MUST]. Usually abbreviated as ps
  • total{Number} - The total number of records in the list, must be an integer of [MUST] no less than 0. Represents the number of records under current conditions, not on this page.
  • keyword{String} - The search keyword to which the list belongs.
  • orderBy{String} - List collation. Multiple collations are separated by commas (,); Positive or reverse order is represented by ASC or desc, with a space interval between the field name. Example: "id desc,name asc"
  • condition{Object} - The set of search criteria to which the list belongs. Attributes may or may not contain keyword fields, if not, it is recommended that the search keyword keyword condition be appended to the parsing (RECOMMMANDED).
  • startTime{Datetime} - Start time, used to search for list data with creation time, usually paired with endTime
  • endTime{Datetime} - End time, same as above

Data Page Example

{
  code: 0,
  msg: 'success',
  data: {
    "pn": 1,
    "ps": 10,
    "total": 100,
    "keyword": "John",
    "orderBy": "id desc, name asc",
    "condition": {},
    "startTime": "2010-11-11 11:11:11",
    "endTime": "2018-11-11 11:11:11",
    "data": [
        {
            "id": 1,
            "name": "John",
            "sex": "male",
            "age": 31
        },
        {
            "id": 2,
            "name": "Lily",
            "sex": "female",
            "age": 28
        }
    ]
  }
}

tree structure

Tree data is used to represent cascading data structures. Tree data MUST be a JSON Object representing the root node of the tree data. Below is a list of optional nodes defined by the standard, and attributes not in the list can expand by themselves [SHOULD].

Node Properties

  • id {Number|String} - The unique identity of the node.
  • text {String} - Name or string used for display.
  • children {Array} - List of child nodes.

sample data

// good
{
  code: 0,
  msg: 'success',
  data: {
    "id": 1,
    "text": "China",
    "children": [
        {
            "id": 10,
            "text": "Beijing",
            "children": [
                {
                    "id": 100,
                    "text": "Dongcheng District"
                },
                {
                    "id": 101,
                    "text": "Xicheng District"
                },
                {
                    "id": 102,
                    "text": "Haidian District"
                }
            ]
        },
        {
            "id": 31,
            "text": "Hainan",
            "children": [
                {
                    "id": 600,
                    "text": "Haikou"
                },
                {
                    "id": 601,
                    "text": "Sanya"
                },
                {
                    "id": 602,
                    "text": "Mount Wuzhi"
                }
            ]
        }
    ]
  }
}


//bad
{
  code: 0,
  msg: 'success',
  data: [
    {
        "id": 1,
        "text": "China",
        "parentId": 0,
    },
    {
        "id": 2,
        "text": "Beijing",
        "parentId": 1,
    },
    {
        "id": 3,
        "text": "Dongcheng District",
        "parentId": 2,
    },
    {
        "id": 4,
        "text": "Xicheng District",
        "parentId": 2,
    }
  ]
}

Keywords: PHP Java Javascript ASP.NET C#

Added by luisluis on Wed, 02 Feb 2022 05:40:38 +0200