Данный узел служит для описания интерфейса конкретного эндпоинта. Интерфейс схож с 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 узел выглядит следующим образом:
В качестве иконки у данного вида узла выступает название HTTP-метода. Контекстное меню выглядит следующим образом:
Rename. Переименовать узел.
Duplicate. Сделать копию узла. Новый узел будет иметь название NodeName [Copy [number]].
Remove node. Удалить узел.
Show in explorer. Открыть папку с узлом в файловом менеджере.
Вкладка ApiRoute узла выглядит следующим образом:
Рассмотрим подробнее верхнюю часть данной вкладки:
На скрине обозначены следующие области:
Http-метод. Данный список совпадает со списком методов из RequestStep узла
Url с поддержкой механизма переменных
Кнопка открытия диалога работы с переменными
Кнопка создания запроса из текущего описания API
Текстовое описание запроса
В левой нижней части расположена область описания запроса. Она разделена на 3 вкладки: Headers, Query parameters и Body для редактирования HTTP-заголовков, query параметров и параметров тела запроса соответственно.
Рассмотрим вкладку Headers. Ее содержимое представлено в табличном виде. Для редактирования заголовков доступны следующие поля:
Название заголовка
Тип значения заголовка (список типов описан выше)
Описание
Поддерживаются все стандартные операции.
Вкладка Query Parameters используется для редактирования query параметров, в остальном по функционалу идентична вкладке Headers.
Как уже было сказано, в ApiRoute узле можно описать несколько тел для одного и того же запроса. Например, по одному и тому же эндпоинту могут приниматься как данные с Content-Type
равным application/json
, так и с application/xml
. Вкладка Body разделена как раз по content-type
на вкладки и имеет следующий вид:
На скрине отмечены следующие области:
Кнопка редактирования текущего content-type
. При нажатии на нее данное поле подменяется на текстовое поле, где можно ввести интересующий content-type
.
Кнопка удаления тела запроса
Кнопка добавления тела запроса
Текущий content-type
узла
Область редактирования тела запроса
Область редактирования тела запроса меняется в зависимости от content-type
по следующему правилу: если content-type
равен application/x-www-form-urlencoded
или multipart/form-data
, то область редактирования принимает табличный вид (аналогичный табличной области в Headers вкладке), в противном случае - текстовый как на скрине выше. В текстовой области в качестве формата описания используется OpenAPI.
В правой нижней области интерфейса вкладки ApiRoute узла расположена области редактирования ответов от сервера. Как уже было сказано, TestMace поддерживает описание нескольких ответов в рамках одного эндпоинта. Интерфейс данной области выглядит следующим образом:
Данный интерфейс разделен на вкладки, отдельно для каждого ответа. В рамках вкладки каждого ответа можно редактировать код ответа, описание, а также HTTP-заголовки и тела ответа, интерфейсы которых идентичны таковым из области запроса.
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#"}