ApiRoute

Данный узел служит для описания интерфейса конкретного эндпоинта. Интерфейс схож с RequestStep узлом. Это и не удивительно - в обоих случаях мы имеем дело с HTTP-запросами.

Основные возможности данного типа узлов:

  • Возможность описания http-заголовков, query параметров, body параметров запроса и HTTP-кодов, HTTP-заголовков, body параметров ответа

  • Использование типов для описания каждого из заголовков, query параметров, body параметров. Поддерживаются следующие типы: string, number, integer, boolean, array и object.

  • Добавление описаний для каждой из сущностей

  • Поддержка описания нескольких параметров тела запроса (в зависимости от content-type)

  • Поддержка описания нескольких возможный ответов от сервера

  • Создание запроса из описания

  • Автодополнение урлов, HTTP-заголовков, query параметров и body параметров в RequestStep узлах.

Обзор интерфейса

Для создание ApiRoute узла необходимо в контекстном меню ApiFolder узла выбрать Add node -> ApiRoute.

Вид узла в дереве проекта

В дереве ApiRoute узел выглядит следующим образом:

Вид ApiRoute узла в дереве проекта

В качестве иконки у данного вида узла выступает название HTTP-метода. Контекстное меню выглядит следующим образом:

Контекстное меню ApiRoute узла
  • Rename. Переименовать узел.

  • Duplicate. Сделать копию узла. Новый узел будет иметь название NodeName [Copy [number]].

  • Remove node. Удалить узел.

  • Show in explorer. Открыть папку с узлом в файловом менеджере.

Интерфейс вкладки

Вкладка ApiRoute узла выглядит следующим образом:

Вкладка ApiRoute узла

Области общих параметров запроса

Рассмотрим подробнее верхнюю часть данной вкладки:

Верхняя часть таба ApiRoute узла

На скрине обозначены следующие области:

  1. Http-метод. Данный список совпадает со списком методов из RequestStep узла

  2. Url с поддержкой механизма переменных

  3. Кнопка создания запроса из текущего описания API

  4. Текстовое описание запроса

Область описания параметров запросов

В левой нижней части расположена область описания запроса. Она разделена на 3 вкладки: Headers, Query parameters и Body для редактирования HTTP-заголовков, query параметров и параметров тела запроса соответственно.

Рассмотрим вкладку Headers. Ее содержимое представлено в табличном виде. Для редактирования заголовков доступны следующие поля:

  • Название заголовка

  • Тип значения заголовка (список типов описан выше)

  • Описание

Поддерживаются все стандартные операции.

Вкладка Query Parameters используется для редактирования query параметров, в остальном по функционалу идентична вкладке Headers.

Как уже было сказано, в ApiRoute узле можно описать несколько тел для одного и того же запроса. Например, по одному и тому же эндпоинту могут приниматься как данные с Content-Type равным application/json, так и с application/xml. Вкладка Body разделена как раз по content-type на вкладки и имеет следующий вид:

Вид вкладки Body интерфейса описания запроса

На скрине отмечены следующие области:

  1. Кнопка редактирования текущего content-type. При нажатии на нее данное поле подменяется на текстовое поле, где можно ввести интересующий content-type.

  2. Кнопка удаления тела запроса

  3. Кнопка добавления тела запроса

  4. Текущий content-type узла

  5. Область редактирования тела запроса

Область редактирования тела запроса меняется в зависимости от content-type по следующему правилу: если content-type равен application/x-www-form-urlencoded или multipart/form-data, то область редактирования принимает табличный вид (аналогичный табличной области в Headers вкладке), в противном случае - текстовый как на скрине выше. В текстовой области в качестве формата описания используется OpenAPI.

Область описания параметров запросов

В правой нижней области интерфейса вкладки ApiRoute узла расположена области редактирования ответов от сервера. Как уже было сказано, TestMace поддерживает описание нескольких ответов в рамках одного эндпоинта. Интерфейс данной области выглядит следующим образом:

Интерфейс редактирования ответов сервера

Данный интерфейс разделен на вкладки, отдельно для каждого ответа. В рамках вкладки каждого ответа можно редактировать код ответа, описание, а также HTTP-заголовки и тела ответа, интерфейсы которых идентичны таковым из области запроса.

Интеграция с RequestStep узлом

TestMace имеет интеграцию с ApiRoute узлами в RequestStep узлах. На данный момент эта интеграция проявляется в автодополнении url, HTTP-заголовков, query параметров, параметров тела запросов RequestStep узлов. Причем, для url-ов в автодополнении участвуют всех url-ы ApiRoute узлов, тогда как для остальных параметров автодополнение работает по следующему алгоритму:

  • Берутся метод и url данного RequestStep узла

  • Ищутся все ApiRoute узлы с такими url и методом

  • Осуществляется поиск по искомому параметру (например, по HTTP-заголовку) среди найденных ApiRoute узлов

Файловое представление

ApiRoute узел представляет из себя папку с названием узла, внутри которой содержится файл index.yml, имеющий следующий формат.

{
"type": "object",
"properties": {
"type": {
"description": "Type of ApiRoute node",
"const": "ApiRoute",
"type": "string"
},
"url": {
"type": "string",
"default": ""
},
"method": {
"$ref": "#/definitions/RequestMethod"
},
"description": {
"type": "string",
"default": ""
},
"requests": {
"$ref": "#/definitions/ApiRequests",
"description": "List of requests"
},
"responses": {
"description": "List of responses",
"type": "array",
"items": {
"$ref": "#/definitions/ResponseParameters"
},
"default": []
},
"children": {
"description": "List of children names",
"type": "array",
"items": {
"type": "string"
},
"default": []
},
"variables": {
"$ref": "#/definitions/NodeVariables",
"description": "Node variables dictionary"
},
"name": {
"description": "Node name",
"type": "string"
}
},
"required": [
"children",
"description",
"method",
"name",
"requests",
"responses",
"type",
"url",
"variables"
],
"definitions": {
"RequestMethod": {
"enum": [
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT"
],
"type": "string"
},
"ApiRequests": {
"type": "object",
"properties": {
"queryParameters": {
"description": "List of query parameters",
"type": "array",
"items": {
"$ref": "#/definitions/QueryParameter"
}
},
"headers": {
"description": "List of headers",
"type": "array",
"items": {
"$ref": "#/definitions/QueryParameter"
}
},
"cookies": {
"description": "List of cookies",
"type": "array",
"items": {
"$ref": "#/definitions/QueryParameter"
}
},
"bodies": {
"description": "List of bodies",
"type": "array",
"items": {
"$ref": "#/definitions/RequestParameters"
},
"default": []
}
},
"required": [
"bodies",
"cookies",
"headers",
"queryParameters"
]
},
"QueryParameter": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"type": {
"enum": [
"array",
"boolean",
"integer",
"number",
"object",
"string"
],
"type": "string"
},
"description": {
"type": "string"
}
},
"required": [
"name",
"type"
]
},
"RequestParameters": {
"type": "object",
"properties": {
"contentType": {
"type": "string"
},
"schema": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
}
},
"required": [
"contentType",
"schema"
]
},
"SchemaRef": {
"type": "object",
"properties": {
"$ref": {
"type": "string"
}
},
"required": [
"$ref"
]
},
"OneOf": {
"type": "object",
"properties": {
"oneOf": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
}
}
},
"required": [
"oneOf"
]
},
"AllOf": {
"type": "object",
"properties": {
"allOf": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
}
}
},
"required": [
"allOf"
]
},
"AnyOf": {
"type": "object",
"properties": {
"anyOf": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
}
}
},
"required": [
"anyOf"
]
},
"ObjectMember": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"object"
]
},
"properties": {
"$ref": "#/definitions/SchemaMember"
},
"required": {
"type": "boolean"
},
"additionalProperties": {
"$ref": "#/definitions/ScalarMember"
},
"description": {
"type": "string"
}
},
"required": [
"type"
]
},
"SchemaMember": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
}
},
"ArrayMember": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"array"
]
},
"items": {
"anyOf": [
{
"$ref": "#/definitions/SchemaRef"
},
{
"$ref": "#/definitions/OneOf"
},
{
"$ref": "#/definitions/AllOf"
},
{
"$ref": "#/definitions/AnyOf"
},
{
"$ref": "#/definitions/ObjectMember"
},
{
"$ref": "#/definitions/ArrayMember"
},
{
"$ref": "#/definitions/ScalarMember"
}
]
},
"description": {
"type": "string"
}
},
"required": [
"items",
"type"
]
},
"ScalarMember": {
"type": "object",
"properties": {
"type": {
"$ref": "#/definitions/ScalarSchemaType"
},
"description": {
"type": "string"
}
},
"required": [
"type"
]
},
"ScalarSchemaType": {
"enum": [
"boolean",
"integer",
"number",
"string"
],
"type": "string"
},
"ResponseParameters": {
"type": "object",
"properties": {
"code": {
"description": "Http-code (e.g. 200, 404)",
"type": "string"
},
"description": {
"type": "string"
},
"headers": {
"type": "array",
"items": {
"$ref": "#/definitions/QueryParameter"
}
},
"content": {
"$ref": "#/definitions/RequestParameters",
"description": "Response body"
}
},
"required": [
"code",
"content"
]
},
"NodeVariables": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}