Hi there!
I am realy sad that OpenAPI specification does not support RPC style of API, because of path centric structure. There is so many tools to describe REST API, but there is no such to describe RPC API. And recently your initiative have appeared with Open API ideology, but without supporting of RPC API style. Why? Could you add it to nearest release?
RPC style APIs could be a side effect of #574. An unfortunate side effect, IMHO.
@webron it seems like that implementation of operations really solves issue of describing RPC API. There is can be some details related to JSON RPC 2.0, for example, but I hope you cover most cases.
Thank you, and if it possible to take part in testing of your new realease, I would glad to join.
Parent: #586.
Following a different thread, it's unlikely #574 will resolve it as it's controlled by the content of the request, not the structure of it. Moving it under #586.
I use swagger spec to describe JSON-RPC in a hacky way, storing method names in paths keys and ignoring non-post operations. Hack is enabled by x-service-type vendored flag.
@vearutop that sounds interesting鈥攄o you have an example you could share?
basePath is used for endpoint value.
x-service-type specifies how to treat swagger.json file.
For this vendor extension we have a patched swagger-ui which envelopes original request to something like {"jsonrpc": "2.0", "method": "getSimpleV1", "params": {"id":3}, "id": 1}.
That simple we benefit from swagger spec and tools not only for our REST, but also for JSON-RPC services.
{
"swagger": "2.0",
"x-service-type": "json-rpc",
"info": {
"title": "DummyAPI",
"version": "master~dirty"
},
"host": "",
"basePath": "/rpc",
"schemes": [
"http",
"https"
],
"paths": {
"getSimpleV1": {
"post": {
"tags": [
"V1"
],
"summary": "Simple Get",
"description": "Get simple by ID",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/SimpleGetParameters"
},
"required": true
}
],
"responses": {
"200": {
"description": "request success",
"schema": {
"$ref": "#/definitions/Simple"
}
}
}
}
}
},
"definitions": {
"Simple": {
"type": "object",
"properties": {
"id_simple": {
"type": "integer"
},
"name": {
"type": "string"
}
}
},
"SimpleGetParameters": {
"type": "object",
"properties": {
"id": {
"type": "integer"
}
}
}
}
}
That's a little disappointing, I was really hoping to see something interesting, like folding of the parameters into the existing document, with clever uses of the flags. Having to use a different library to pull meaningful data is unfortunate.
Sorry, @wparad, I did not mean to make you sad (mind hacky way disclaimer).
Not sure I got you right, by "folding of the parameters into the existing document" do you mean having JSON-RPC envelope structures built in schema definition? What is "different library"?
@vearutop, could you clarify, your API has structure according to JSON RPC 2.0 or you are just using RPC style for URL resources?
@SvyatoslavVasiliev, API is serving valid JSON RPC 2.0 structures.
JSON RPC enveloping (including batch requests) is done by client and server according to spec.
method, params and result is defined and validated by swagger.json path, post-parameters and post-responses-200 accordingly.
Endpoint URI is defined in swagger.json as basePath.
Service host is dynamic and loadbalanced, so it is not present in swagger.json.
Actually this swagger.json is not valid, since it does not have / at the beginning of paths keys.
But this approach made possible to achieve "compatibility" with least effort.
@vearutop, thank you, as I am looking for some tool to specify my JSON RPC API, I will try your approach in swagger. But unfortunately, as @wparad already said, standard swagger library won't be able to work with it fully. For example if I try to upload your specification in on-line swagger editor I won't able to make API requests, because of wrong auto generated URL.
hi @webron, I was wondering if there's any update on this issue? thanks!
Hi, same here. I would really be glad to hear that OpenAPI (Swagger) can handle JSON RPC style APIs.
+1 for this. Swagger is de facto standard. It should feel the urge to influence the standard of RPC documentation as well.
+1000
REST = SQL Web API != Computer Science + Information Technology + Computational Science
Trying to implement google maps in sql may help to understand the most stubborn soul.
Data manipulation and, side by side, function call is a must.
By the way json-rpc 2 is pretty simple, good and stable.
OpenAPI provides JSON Schema to describe a wide range of payloads. If an API provider decides to create a single path item object with many different payloads in order to tunnel procedure calls, then OpenAPI can do that. The support for JSON Schema oneOf in OpenAPI V3 will make that even easier.
If people want to build tooling that map those payloads into UI as if they were different path item objects, then they are free to do so. I don't believe that the OpenAPI spec should try and standardize a mapping between those payloads and native HTTP constructs. If there is sufficient community support to standardize that mapping then I would encourage that community to create it and encourage tool builders to support it.
@darrelmiller
I have to admit it's a bit harsh to understand all the terms you cite for an outsider for now o:
(But i have a second screen diffusing the linux foundation mooc at this same amazing time, and sure, that will help to catch in the long run).
I will follow your tips and wait/contribute example from/to the community.
By the way, thanks for the quick answer, and what a good teasing for the v3!
I ended up using @vearutop 's approach to create a demo. We have a single endpoint for JSON-RPC calls that each have a different method. But I've explained how we resolved it in the main "info" > "description" section of the following OAS3 that I've pushed here:
https://github.com/ltfschoen/swagger/blob/master/scon_substrate_0.4.0_swagger.json
It can be viewed with Swagger UI here: https://app.swaggerhub.com/apis-docs/scon/substrate/0.4.0
And I also imported into Readme.io here: https://substrate.readme.io/v1.0.0/reference
I ran into this issue recently too and ended up here from swagger-api/swagger-codegen#4274. I finally have something that is working relatively well for what I am doing so I created a JSON-RPC 2.0 OAS sample gist for anyone else that may benefit from it. You can copy/paste it into http://editor.swagger.io/ to experiment with it.
There is a simple POST that includes a JSON-RPC param. I also showed how to use a ref (in conjunction with allOf) to avoid duplicating the method, id and jsonrpc properties.
Copy of gist:
{
"x-send-defaults": true,
"openapi": "3.0.0",
"x-api-id": "json-rpc-example",
"info": {
"title": "JSON-RPC OpenAPI",
"version": "1.0.0",
"description": "Example of how to describe a JSON-RPC 2 API in OpenAPI"
},
"servers": [
{
"url": "http://127.0.0.1:3000"
}
],
"paths": {
"/examplePost": {
"post": {
"operationId": "examplePost",
"deprecated": false,
"summary": "Example of JSON-RPC2 Post",
"description": "Example post using JSON-RPC params.",
"tags": [
"JSONRPC"
],
"parameters": [],
"responses": {
"200": {
"description": "Successful response"
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"method",
"id",
"jsonrpc",
"params"
],
"properties": {
"method": {
"type": "string",
"default": "examplePost",
"description": "Method name"
},
"id": {
"type": "integer",
"default": 1,
"format": "int32",
"description": "Request ID"
},
"jsonrpc": {
"type": "string",
"default": "2.0",
"description": "JSON-RPC Version (2.0)"
},
"params": {
"title": "Parameters",
"type": "object",
"required": [
"jsonParam"
],
"properties": {
"jsonParam": {
"type": "integer",
"default": 1,
"description": "A param to include"
}
}
}
}
}
}
}
}
}
},
"/examplePost2": {
"post": {
"operationId": "examplePost2",
"deprecated": false,
"summary": "Example of JSON-RPC2 Post",
"description": "Example post using JSON-RPC params. Also uses a ref to avoid duplicating properties.",
"tags": [
"JSONRPC"
],
"parameters": [],
"responses": {
"200": {
"description": "Successful response"
}
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/examplePost"
}
}
}
}
}
}
},
"x-headers": [],
"x-explorer-enabled": true,
"x-proxy-enabled": true,
"x-samples-enabled": true,
"x-samples-languages": [
"curl",
"node",
"ruby",
"javascript",
"python"
],
"components": {
"schemas": {
"JsonRpcRequired": {
"type": "object",
"required": [
"method",
"id",
"jsonrpc"
],
"properties": {
"method": {
"type": "string",
"default": "examplePost",
"description": "Method name"
},
"id": {
"type": "integer",
"default": 1,
"format": "int32",
"description": "Request ID"
},
"jsonrpc": {
"type": "string",
"default": "2.0",
"description": "JSON-RPC Version (2.0)"
}
},
"discriminator": {
"propertyName": "method_name"
}
},
"examplePost": {
"allOf": [
{
"$ref": "#/components/schemas/JsonRpcRequired"
},
{
"type": "object",
"properties": {
"params": {
"title": "Parameters",
"type": "object",
"required": [
"jsonParam"
],
"properties": {
"jsonParam": {
"type": "integer",
"default": 1,
"description": "A param to include"
}
}
}
}
}
]
}
}
},
"tags": []
}
Most helpful comment
+1 for this. Swagger is de facto standard. It should feel the urge to influence the standard of RPC documentation as well.