# API Endpoint Task

These tasks describe API contracts, providing a detailed description of how operations on entities are performed and the rules that govern those operations.

The majority of these tasks should define a contract holistically - including, but not limited to, a description of the endpoint, the HTTP method, endpoint path, query parameters, required security actions, request and/or response body, validation rules, and any additional information that further describes the purpose or function of the endpoint or inputs that may affect its behavior.

Components of an API contract

Component Description
Description States the intended use or purpose of the endpoint
Method The HTTP method being used
Path Root level path of the endpoint
Query parameters Document name and type of query parameters (if any), additional descriptions as needed
Required action(s) SecurityModel action(s) required to call the endpoint
Request body JSON mock or TypeScript description of request body (if applicable)
Validation rules Document validation rules (if any) that are applied to the incoming request (required, min/max, charset, etc)
Response body JSON mock or TypeScript description of response body (if applicable)

# Examples

# Example GET endpoint

# Title

BE: Create endpoint to get application roles

# Description

This endpoint should return roles belonging to the application matching the applicationRef specified in the URL parameter of the same name. If the application is not found it should return an HTTP status code of 404. If the application exists but has no roles the results field should be an empty array.

The endpoint should match the following criteria:

Method GET
Path /v1/application/{applicationRef}/role
Required Action View Application Roles
Query Parameters pageSize: number, pageNumber: number, roleName: string

Return Interface:

{
  "pageInfo": {
    "pageNumber": 1,
    "pageSize": 10,
    "numberOfPages": 10,
    "numberOfRecords": 100
  },
  "messages": [],
  "results": [
    {
      "roleRef": 344,
      "name": "Administrator",
      "description": "Security Model Administrator",
      "isActive": true,
      "createdDate": "2024-07-02T12:51:27+0000", // ISO-8601 datetime string in UTC time
      "createdBy": 476,
      "updatedDate": null, // ISO-8601 datetime string in UTC time
      "updatedBy": null
    }
  ]
}

# Additional Considerations

# Use self-documenting values

In the above example, the return interface portion of the description represents the JSON structure that the endpoint will return as well as the type of each field. The values may be contrived but should convey a common example that this endpoint will return. For example, if the field is a date in ISO-8601 format, the example value in JSON should conform to that standard.

# TypeScript usage

Return interfaces may optionally be documented using TypeScript types instead of JSON. This example illustrates the equivalent return interface documentation as the JSON in the previous example.

type GetApplicationRolesResponse = {
  pageInfo: PageInfo;
  messages: string[];
  results: Role[];
};

type Role = Tracked & {
  roleRef: number;
  name: string;
  description: string;
  isActive: boolean;
};

type Tracked = {
  createdDate: string; // ISO-8601 datetime string in UTC time
  createdBy: number | null;
  updatedDate: string | null; // ISO-8601 datetime string in UTC time
  updatedBy: number | null;
};

# Omit MidlandResult

Because all responses must be wrapped in the MidlandResult interface, the pageInfo, messages, and results fields may optionally be omitted in favor of documenting only the contents of the results field.

If this choice is made, however, it must be documented in the description that the return value/interface is wrapped in a MidlandResult and, most importantly, indicated whether or not the response is paginated.

Example JSON:

// Return example for results field in MidlandResult (paginated)
[
  {
    "roleRef": 344,
    "name": "Administrator",
    "description": "Security Model Administrator",
    "isActive": true,
    "createdDate": "2024-07-02T12:51:27+0000", // ISO-8601 datetime string in UTC time
    "createdBy": 476,
    "updatedDate": null, // ISO-8601 datetime string in UTC time
    "updatedBy": null
  }
]

Example TypeScript:

type GetApplicationRolesResponse = MidlandResult<Role[]>;

type Role = Tracked & {
  roleRef: number;
  name: string;
  description: string;
  isActive: boolean;
};

# Example POST endpoint

# Title

BE: Create endpoint to create a new application role

# Description

This endpoint should create a new role belonging to the application matching the applicationRef specified in the post body parameter of the same name. If the application is not found it should return an HTTP status code of 404.

The endpoint should match the following criteria:

Method POST
Path /v1/role
Required Action Edit Application Actions
Query Parameters N/A

Request body interface

{
  "applicationRef": 5,
  "roleName": "Administrator",
  "description": "Security Model Administrator",
  "actions": [
    // actions is an ActionRef array
    104, 110, 112
  ]
}

Validation rules

Field Rule(s)
applicationRef required
roleName required, minLength: 5, maxLength: 30, Alphanumeric + " ", "-", "_", and ","
description required, minLength: 10, maxLength: 200

# Additional considerations

# Inline validation rules

If validation rules are simple, they may be placed in the request body as comments, instead of a table of their own.

{
  "applicationRef": 5, //required
  "applicationName": "Administrator", //required, 5-30 chars
  "description": "Security Model Administrator", //required, 10-200 chars
  "actions": [104, 110, 112]
}