Это старая версия документа!
Оригинал статьи: X-Road: Message Protocol for REST
Все REST сервисы должны быть описаны в соответствии со стандартом OPENAPI3. Пример правильно описанного сервиса смотрите в приложении.
Используется протокол HTTP версии 1.1.
Участник/Подсистема отправителя указываются в заголовке HTTP. Используемый сервис указывается в самом URL в виде параметров.
Формат запроса:
{http-request-method} /{protocol-version}/{serviceId}[/path][?query-parameters]
[X-Road instance]/[member class]/[member code]/[subsystem code]/[service code].В каждом запросе должен присутствовать следующий заголовок HTTP:
X-Road-Client: {client}
{client} — информация о том, кто обращается к сервису. Состоит из следующих частей:
[X-Road instance]/[member class]/[member code]/[subsystem code].
[Subsystem code] является не обязательным.
Например:
X-Road-Client: central-server/GOV/70000004/e-services
При ответе Сервер Безопасности устанавливает следующие заголовки HTTP:
Например:
X-Road-Client: central-server/GOV/70000004/e-services X-Road-Service: central-server/GOV/70000002/gns-service/GnsTransportByPin/v1 X-Road-Id: fa2e18a5-c2cb-4d09-b994-f57727f7c3fb X-Road-Request-Hash: 4c519cf0-0e5e-4ccf-b72b-8ed6fe289e6e X-Road-Request-Id: f92591a3-6bf0-49b1-987b-0dd78c034cc3
Если Вы обращаетесь к сервису, то рекомендуется включать заголовок Accept, позволяющий указать в каком формате Вы хотите получить ответ. Например:
Accept: application/xml
Если заголовок Accept не указан явно, то Сервер Безопасности самостоятельно ставит значение:
application/json
Пример запроса:
GET /r1/INSTANCE/CLASS2/MEMBER2/SUBSYSTEM2/BARSERVICE/v1/bar/zyggy?some_parameter=1&another_parameter=test
Чтобы отправить запрос к определенному Серверу Безопасности, необходимо включить в запрос следующий заголовок HTTP:
X-Road-Security-Server: [X-Road instance]/[member class]/[member code]/[server code]
В случае возникновении ошибки во время обработки запроса или же на стороне X-Road, в ответ включается следующий заголовок:
X-Road-Error: [error type]
Заголовок будет содержать только тип ошибки. Детальная информация, как код ответа HTTP, тело сообщения об ошибки и т.д. будет находиться в теле ответа.
Все возникающие ошибки между клиентом и Сервером Безопасности можно поделить на 4 типа:
Для того чтобы различить, на чьей стороне возникла ошибка при коде статуса 500, необходимо обращать внимание на заголовок X-Road-Error: Если заголовок X-Road-Error отсутствует, то ошибка возникла на стороне сервиса, иначе – со стороны X-Road. В таком случае, дополнительная информация отображается в поле type в теле ответа. Например:
Server.ServerProxy.ServiceFailed означает, что Сервер Безопасности не получил ответ от сервиса.Server.ServerProxy.DatabaseError означает, что на Сервере Безопасности возникла внутренняя ошибка.Server.ClientProxy.OutdatedGlobalConf указывает на проблему со стороны обратившегося Сервера Безопасности.
1. Всё сработало на стороне Сервера Безопасности, но сервис вернул ошибку.
HTTP status code: 405
Response body:
"timestamp":"2019-03-21T09:45:19.904Z", "status":405, "error":"Method Not Allowed", "message":"Request method 'PUT' not supported", "path":"/v3/pet/findByStatus"
HTTP headers:
Content-Type: application/json;charset=utf-8 Date: Thu, 21 Mar 2019 09:45:19 GMT x-road-id: 5ea48ae9-15c1-465a-be15-9b6ef2c7ef4a x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: yFOLGuJ0zmLhZSgwp3ooSBQbR9ejSvTc6p6FvBmcSEB2tDD6bxpjiv8sHORxqz4MMgEADH7IcARNprLfEwudNw== Content-Length: 159
2. Всё сработало на стороне Сервера Безопасности, но на стороне сервиса возникли технические неполадки
HTTP status code: 500
Response body:
{
"type":"Server.ServerProxy.NetworkError",
"message":"Connect to 10.139.178.1:8080 [/10.139.178.1] failed: Connection timed out (Connection timed out)",
"detail":"9bc95b6e-2f1d-4a41-a7e6-11eda7d734d5"
}
HTTP headers:
Date: Thu, 21 Mar 2019 11:42:03 GMT Content-Type: application/json;charset=utf-8 X-Road-Error: Server.ServerProxy.NetworkError Content-Length: 199
3. Клиент послал запрос, не соответствующий протоколу сообщений X-Road для REST
HTTP status code: 400 Response body:
{
"type": "Client.BadRequest",
"message": "Error parsing the client's REST request. Please that the request format corresponds to the X-Road Message Protocol for REST (r1).",
"detail": "018cbcae-537e-421b-b6f6-2608dc97bd90"
}
HTTP headers:
Date: Thu, 21 Mar 2019 11:45:12 GMT Content-Type: application/json;charset=utf-8 X-Road-Error: Client.BadRequest Content-Length: 167
4. На стороне сервера безопасности возникли технические неполадки
HTTP status code: 500
Response body:
{
"type":"Server.ServerProxy.DatabaseError",
"message":"Error accessing database (serverconf)",с
"detail":"3c4d0f08-440f-417f-b935-bc801e103d51"
}
HTTP headers:
Date: Thu, 21 Mar 2019 11:57:11 GMT Content-Type: application/json;charset=utf-8 X-Road-Error: Server.ServerProxy.DatabaseError Content-Length: 141''
Сервис магазина питомцев описан по стандарту OPENAPI3. Полное описание сервиса смотрите в Приложении 1.
Пример предполагает, что serviceID привязан к https://petstore.niis.org/.
Обратите внимание:
Сервис - /pets/{petId}
Метод - GET.
Описание - Находит питомца по ID.
Параметры - PetId – ID питомца.
Вызов сервиса через X-Road:
curl -X GET "https://{securityserver}/r1/{serviceId}/v2/pets/1124" -H "accept: application/json" -H "X-Road-Client: {client}"
Ответ:
{
"id": 1124,
"name": "Siddu",
"photoUrls": [],
"tags": [],
"status": "Offline"
}
Код статуса: 200
Заголовки:
Content-Type: application/json;charset=utf-8 Date: Thu, 21 Mar 2019 12:36:39 GMT x-road-id: 29f4d011-ef17-4f2f-9bb1-0452ce17d3f5 x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: Xvx9V2U5c5RhDUiXpVLtW7L8vTd5cM2IOBU2n9efEk7/m3ECKyGAp7yTpJpTWpo6HcmwSaGO+cinxMVKjxJTOQ== Content-Length: 1148
Сервис - /pets/{petId}
Метод - PUT
Описание - Обновляет питомца по ID.
Параметры - body – объект Pet, который будет обновлён.
Вызов сервиса напрямую:
curl -X PUT "https://petstore.niis.org/v2/pets/5657082955040009" -H "accept: application/json" -H "Content-Type: application/json" -d '{ "id": 0, "category": { "id": 0, "name": "string" }, "name": "doggie", "photoUrls": [ "string" ], "tags": [ { "id": 0, "name": "string" } ], "status": "available"}'
Вызов сервиса через X-Road:
curl -X PUT "https://{securityserver}/r1/{serviceId}/v2/pets/5657082955040009" -H "accept: application/json" -H "Content-Type: application/json" -H "X-Road-Client: {client}" -d '{ "id": 0, "category": { "id": 0, "name": "string" }, "name": "doggie", "photoUrls": [ "string" ], "tags": [ { "id": 0, "name": "string" } ], "status": "available"}'
Ответ:
{
"id": 5657082955040009,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
Код статуса: 200
Заголовки:
Date: Thu, 21 Mar 2019 12:43:33 GMT x-road-id: acdb2c7a-c705-41c2-b595-4cd62e78316e x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: MOEfTqBjdqYiX3db9hxJ6JvHvCpYqfA6t0Uhdv6g2I29fMY8ld4CbN8tslj6mUQPXoRaUdPm7NdZeAYTg6zi+A== Content-Length: 0
Сервис - /pets/{petId}
Метод - POST
Описание - Добавляет нового питомца.
Параметры - body – объект Pet, который будет добавлен.
Вызов сервиса напрямую:
curl -X POST "https://petstore.niis.org/v2/pets" -H "accept: application/json" -H "Content-Type: application/json" -d '{ "id": 0, "category": { "id": 0, "name": "string" }, "name": "doggie", "photoUrls": [ "string" ], "tags": [ { "id": 0, "name": "string" } ], "status": "available"}'
Вызов сервиса через X-Road:
curl -X POST "https://{securityserver}/r1/{serviceId}/v2/pets" -H "accept: application/json" -H "Content-Type: application/json" -H "X-Road-Client: {client}" -d '{ "id": 0, "category": { "id": 0, "name": "string" }, "name": "doggie", "photoUrls": [ "string" ], "tags": [ { "id": 0, "name": "string" } ], "status": "available"}'
Ответ:
{
"id": 5657082955040122,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
Код статуса: 200
Заголовки:
Date: Thu, 21 Mar 2019 12:49:38 GMT x-road-id: dcaaa3a2-a158-41e1-8775-309848052358 x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: VCNZdwTxl7m3XC6Mpfw1H6qJUtBcm3Y6tfCvg5b3W/fb2RRXsLF9wftR3u6ElclE+RFaiAN/OkSz02fAYbNKaw== Content-Length: 0
Сервис - /pets/{petId}/images
Метод - POST
Описание - Загружает изображение питомца.
Параметры:
• PetID – Id питомца.
• AdditionalMetaData – дополнительная информация.
• File – загружаемый файл.
Вызов сервиса напрямую:
curl -X POST "https://petstore.niis.org/v2/pets/1124/images" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "file=@A-fluffy-cat-looking-funny-surprised-or-concerned.jpg;type=image/jpeg"
Вызов сервиса через X-Road:
curl -X POST "https://{securityserver}/r1/{serviceId}/v2/pets/1124/images" -H "accept: application/json" -H "Content-Type: multipart/form-data" -H "X-Road-client: {client}" -F "file=@A-fluffy-cat-looking-funny-surprised-or-concerned.jpg;type=image/jpeg"
Ответ:
{
"code":200,
"type":null,
"message":"additionalMetadata: null\nFile uploaded to ./file, 170025 bytes"
}
Код статуса: 200
Заголовки:
Content-Type: application/json;charset=utf-8 Date: Thu, 21 Mar 2019 13:02:29 GMT x-road-id: 86e081a6-ec16-4b8d-b729-963f9659a80c x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: EycIkZAz4WMvbKgnBvd0wUcN4A4w0RZMvugD36ZJ2PpwwGZuMGfxCoO4C0ZC3c4LBGF0rh61vunL3ssZV6TB3Q== Content-Length: 100
Сервис - /pets/{petId}
Метод - DELETE.
Описание - Удаляет питомца.
Параметры - PetId – Id питомца.
Вызов сервиса напрямую:
curl -X DELETE "https://petstore.niis.org/v2/pets/1124" -H "accept: application/json"
Вызов сервиса через X-Road:
curl -X DELETE "https://{securityserver}/r1/{serviceId}/v2/pets/1124" -H "accept: application/json" -H "X-Road-Client: {client}"
Ответ: <пусто>
Код статуса: 200
Заголовки:
Date: Thu, 21 Mar 2019 12:49:38 GMT x-road-id: 6209d61b-6ab5-4443-a09a-b8d2a7c491b2 x-road-client: DEV/COM/222/TESTCLIENT x-road-service: DEV/COM/222/TESTSERVICE/petstore x-road-request-id: f92591a3-6bf0-49b1-987b-0dd78c034cc3 x-road-request-hash: lQBoldcyuI3BerjHfkleRQ45AyYoFlF7zXSN6yH/RwvTNWEcsTQM18EfqMxYfdkyGGB26oxAjAWv/AcfmZF7og== Content-Length: 0
openapi: 3.0.0
info:
description: >-
This is a sample server Petstore server.
version: 1.0.0
title: Petstore
contact:
email: info@niis.org
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: 'https://niis.org'
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
externalDocs:
description: Find out more about our store
url: 'https://niis.org'
paths:
/pets:
get:
tags:
- pet
summary: Get pets from store
description: Search pets
operationId: getPets
parameters:
- name: term
in: query
description: search term
required: false
schema:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
post:
tags:
- pet
summary: Add a new pet to the store
description: ''
operationId: addPet
responses:
'201':
description: pet created
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
'/pets/{petId}':
get:
tags:
- pet
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
put:
tags:
- pet
summary: Update an existing pet
description: ''
operationId: updatePet
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Pet updated
'400':
description: Invalid ID supplied
'404':
description: Pet not found
'405':
description: Validation exception
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
$ref: '#/components/requestBodies/Pet'
delete:
tags:
- pet
summary: Deletes a pet
description: ''
operationId: deletePet
parameters:
- name: api_key
in: header
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Pet deleted
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
'/pets/{petId}/images':
post:
tags:
- pet
summary: Uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
additionalMetadata:
description: Additional data to pass to server
type: string
file:
description: file to upload
type: string
format: binary
/store/inventories:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/orders:
post:
tags:
- store
summary: Place an order for a pet
description: ''
operationId: placeOrder
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid Order
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
description: order placed for purchasing the pet
required: true
'/store/orders/{orderId}':
get:
tags:
- store
summary: Find purchase order by ID
description: >-
For valid response try integer IDs with value >= 1 and <= 10.
Other values will generated exceptions
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
type: integer
format: int64
minimum: 1
maximum: 10
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
'400':
description: Invalid ID supplied
'404':
description: Order not found
delete:
tags:
- store
summary: Delete purchase order by ID
description: >-
For valid response try integer IDs with positive integer value.
Negative or non-integer values will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: integer
format: int64
minimum: 1
responses:
'200':
description: Purchase order deleted
'400':
description: Invalid ID supplied
'404':
description: Order not found
/users:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
default:
description: successful operation
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Created user object
required: true
/users/login:
get:
tags:
- user
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: true
schema:
type: string
responses:
'200':
description: successful operation
headers:
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
'400':
description: Invalid username/password supplied
/users/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
responses:
default:
description: successful operation
'/users/{username}':
get:
tags:
- user
summary: Get user by user name
description: ''
operationId: getUserByName
parameters:
- name: username
in: path
description: 'The name that needs to be fetched. Use user1 for testing. '
required: true
schema:
type: string
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid username supplied
'404':
description: User not found
put:
tags:
- user
summary: Updated user
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that need to be updated
required: true
schema:
type: string
responses:
'200':
description: User updated
'400':
description: Invalid user supplied
'404':
description: User not found
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
description: Updated user object
required: true
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
'200':
description: User deleted
'400':
description: Invalid username supplied
'404':
description: User not found
externalDocs:
description: Find out more
url: 'https://niis.org'
servers:
- url: 'https://petstore.niis.org/v2'
- url: 'http://petstore.niis.org/v2'
components:
requestBodies:
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
description: List of user object
required: true
Pet:
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
description: Pet object that needs to be added to the store
required: true
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: 'http://petstore.niis.org/oauth/dialog'
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header
schemas:
Order:
type: object
properties:
id:
type: integer
format: int64
petId:
type: integer
format: int64
quantity:
type: integer
format: int32
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
complete:
type: boolean
default: false
xml:
name: Order
Category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Category
User:
type: object
properties:
id:
type: integer
format: int64
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
password:
type: string
phone:
type: string
userStatus:
type: integer
format: int32
description: User Status
xml:
name: User
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
Pet:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
xml:
name: Pet
ApiResponse:
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string