Skip to content
ADP
API Design PrincipleBETA

[ADP-5] DRAFT ADP Implementation Guide 1st phase

Introduction

For those new to ADP, it can be overwhelming. This guide emphasizes some of the most important principles in ADP, ensuring that developers understand where to start.

INFO

This document is biased towards designing internal APIs (as COMPONENT_INTERNAL) as the API audience, and developers/teams who want to use ADP as a starting point for design standards, so it will only reveal the key standards as much as possible. Other non-essential standards will be marked separately in the second phase of the import document. For public APIs used by external users, theoretically you must try to meet most of the standards, unless the API audience is a specific partner and has special requirements.

Before You Start

Take a deep breath. ADP is designed to provide comprehensive coverage of API design principles, not to overwhelm you. It may look daunting, but its purpose is to ensure comprehensiveness, not to make developers feel lost. If you have any doubts about any aspect of the design, you can always discuss it with me (although changes may not be guaranteed, as this depends on various factors).

  • If your API is for COMPONENT_INTERNAL use, you can basically (MAY) modify any principle to solve the difficulties you encounter in practice.
    • It is recommended to provide feedback on the changes made in the project, to inform the ADP owner whether the principles need to be updated.
  • The modified principles should (SHOULD) be consistent throughout the project.

Choose API-first or code-first

While we recommend API-first, we also understand that sometimes code implementation may need to be done first, and then write the documentation according to the requirements. The API-first approach emphasizes designing the API before implementing any code, which ensures that the API can meet the needs of consumers (whether they are internal developers or external developers) from start to finish, and allows front-end and back-end work to be done separately. In addition, this approach also facilitates API testing, even before the actual development of the API, as long as the API documentation is designed first, a test environment can be created.

What is API-first?

API-first is a development method that designs and reaches consensus on the API before writing any code. This ensures that all stakeholders have a clear understanding of the functionality and requirements of the API, which better aligns with development and business goals.

See API-first.

Choose the right API documentation tool

API documentation in our use case is now in OpenAPI format, consisting of simple JSON/YAML files. We recommend using the YAML file format, as it is easy to split; however, there are also tools that can convert between YAML and JSON, so you don't have to worry too much about the file format.

Although editing YAML/JSON is not too difficult, understanding how to edit OpenAPI content still has a learning curve; we recommend choosing the right OpenAPI editor. Apidog is a good choice, but other tools such as Swagger Editor or Stoplight can also be considered.

Remember, the most important thing is the final output of the YAML/JSON file, and the online editor is just a convenient tool to use.

apidog

It should be noted that there are some limitations when using apidog as an editor.

For example, it does not allow customizing the response MIME type to a custom JSON format, and it may not be intuitive to add custom properties (such as x-audience) in the endpoint.

Despite these limitations, apidog is still a suitable starting point for starting API documentation.

We encourage you to edit the original API file in your favorite editor, after you are familiar with OpenAPI.

For writing OpenAPI files, you can refer to OpenAPI Complete Example, and start with the specification from OpenAPI Overview. Some of the more important parameters are as follows:

Define API Audience

The API audience will affect the strictness of the API specification. Internal APIs are expected to be more flexible, while external APIs will be more strict. Understanding your audience helps make effective design decisions that meet their needs. For internal APIs, we can mark X-Audience as COMPONENT_INTERNAL directly in the info field of the OpenAPI file, or not mark it, as long as this file only flows within the internal team.

However, when we have enough API accumulation and want to establish a company-level API Portal (internal), we hope that we can review and add the audience field to each API file at that time.

See API Audience.

Define OperationId

OperationId is a concise and clear identifier used to describe the purpose or operation of the API. It will be displayed as the name of that operation in any OpenAPI viewer. Please refer to OperationID.

Version Control

Choose your version control strategy: For specific internal APIs, we understand that they may iterate very quickly. Therefore, we define APIs for internal use that may not be version controlled. However, for external APIs, semantic version control (SemVer) should be followed to clearly communicate changes to consumers.

See API Version Control for more information.

Decompose API Requests into API Components

If you choose API-first, sit down and try to write down "API User Stories". This will help you define the functionality and requirements of the API from the consumer's perspective.

For example, suppose you are designing an API for a simple e-commerce platform. Your API user story might look like this:

"As a customer, I want to be able to view my order history so that I can track my past purchases."

This API user story can guide your API design to ensure that it meets the needs of the customer. In fact, a (RESTful) API can be composed of several components:

  • Path
  • HTTP verb
  • (Optional) Query parameters
  • (Optional) Headers, including request and response
  • (Optional) Request payload
  • Response code
  • (Optional) Response body

The process of designing a RESTful API is no secret; it's just about putting the right elements in the right places. This may be a challenge for novice API designers, whether you are a front-end or back-end developer.

The process of "decomposing requirements into API components" will require some experience and learning, and you can get inspiration by looking at well-known public APIs.

URL/Path Design

Path design is the first important component of API design, and it is particularly challenging.

During the API review period (if necessary), it is common to redesign the URL design, which may not be easy for novices to get right the first time.

The path must represent the resource to which the "clear intent" of this API points, and be used in conjunction with the HTTP verb to make it easy for developers to see the purpose of this API.

Using the API story above as an example, we should use a design like this:

GET /order-history

Instead of

GET /api/get

For design around "resources", please refer to Resource-Oriented Design.

HTTP Methods

HTTP verbs are the second most important component in RESTful, and they are used in conjunction with the path to express the "main" thing this API wants to do.

The most commonly used ones are GET, POST. DELETE/PATCH/PUT are less commonly used.

Please refer to several specifications related to HTTP Methods.

About idempotence and idempotent keys: It is recommended to introduce them when needed.

Payload/Response Design

Please refer to ADP-701: JSON Structure and Nesting for principles of effective structured payload and response. Ensure that your API response is consistent and provides meaningful error messages.

When designing the fields of the payload/response, you should follow the format conventions in OpenAPI rather than just specifying the fields as strings, please refer to OpenAPI Format Conventions.

INFO

About field naming conventions: camelCase/snake_case is not wrong, this specification recommends using camelCase, but you can use consistent snake_case within the team if agreed upon.

In the future, when the API governance maturity increases, we will consider whether complete uniformity is necessary.

Error Design

API errors are a necessary but often overlooked part, but designing error responses is essential for a good and consistent developer experience (DX). Please try to follow the principles in ADP-401: HTTP Problem Basics as much as possible, to standardize error responses between APIs.

This specification considers error design to be of high priority.

A basic problem response is as follows:

json
{
  "type": "about:blank",
  "title": "human readable string to the main part of the problem",
  "status": "HTTP Status",
  "detail": "human readable string of how to fix the problem"
}

type

Designing problem types can be a challenge, so it is not considered necessary for first phase import here, please refer to Problem Type Design for details.

When our API governance is mature enough, we may need to revisit and supplement the type.

Event Design

When designing event-related APIs, please consider implementing the principles outlined in Event as Part of API Design and CloudEvents. Ensure that the events comply with the specification, and event consumers can easily understand and process them.

About Headers

HTTP defines a series of standard headers, and also allows custom headers. Sometimes, something you want to achieve may already be solved by standard headers, so you don't need to do it through response/payload/query parameters. Sometimes you may need to design new custom headers. See Common HTTP Headers.

About Query Parameters

Query parameters do not have strict specifications, only some common query conventions, please refer to Query Parameter Conventions.

Response Status Codes

See HTTP Status Codes, at least one set of 200(2xx) responses and 4xx/5xx responses should be defined for an API endpoint.

Summary

Explore the ever-expanding OpenAPI Complete Example for additional API design inspiration. I strive to create API examples that follow ADP guidelines as much as possible.

Please feel free to discuss your API design with me.

Changelog

  • 2024.09.26 Modified the first phase import requirement.