In my play framework application, I have registered APIs in route file as:
POST /api/rmt-create-request controllers.Api.CreateRMTRequestForm
On action of controller, I am using following code to access formData submitted with form submit as :
public Result CreateRMTRequestForm()
{
Map<String, String[]> params = request().body().asMultipartFormData().asFormUrlEncoded();
Its working fine as API when I submit the form with forntend application.
I am trying to create APIs documentation with swagger.ui in which within swagger.json file I have written following JSON data.
"paths": {"/api/rmt-create-request": {
"post": {
"tags": [
"RMT APIs"
],
"description" : "Return newly created request data",
"operationId": "create-new-rmt-request",
"consumes": ["application/x-www-form-urlencoded"],
"parameters": [
{
"name": "rootNodeName",
"in": "formData",
"description": "Root node class name for item",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/rmt-request-data"
}
}
}
},
"default": {
"$ref": "#/components/responses/default"
}
}
}
},
While inspecting RequestHeader data, its not showing content-Type property with value 'multipart/form-data' as well as formData are not attached, which makes controller to throw null exception.
Can anyone help whats missing in swagger.json file ?
You are mixing OpenAPI 2.0 and 3.0 syntax.
In OpenAPI 3.0, request body (including form data) is defined using the requestBody keyword instead of in: formData parameters.
Also, OAS3 does not use consumes. The media types consumed by the operation are specified inside the requestBody.
"paths": {
"/api/rmt-create-request": {
"post": {
"tags": [
"RMT APIs"
],
"description": "Return newly created request data",
"operationId": "create-new-rmt-request",
"requestBody": {
"content": {
"multipart/form-data": { // or "application/x-www-form-urlencoded" - depending on what you need
"schema": {
"type": "object",
"properties": {
"rootNodeName": {
"type": "string",
"description": "Root node class name for item"
}
}
}
}
}
}
}
}
}
More information: Describing Request Body
Related
We have implemented swagger using OpenAPI 3.
We have a requirement where the external request will be sent with a path "{host}/v1/names" which will then be interpreted at gateway level and forwarded as "{host}/api/v1/names" to the deployed springboot application
In the springboot application we are using rest controller with
#RequestMapping(value="/api/v1/names")
So, when OpenApi Json is generated to be used in swagger, it defines path as "/api/v1/names". However, since external customer would use "/v1/names" to access the API, we want to show "/v1/names" in swagger and OpenApi json
Current JSON looks like this:
{
"openapi": "3.0.1",
"info": {
"title": "External API",
"description": "This set of API is used to serve external clients",
"version": "0.1"
},
"servers": [
{
"url": "https://api.xyz.net/",
"description": "Live"
}
],
"paths": {
"/api/v1/names": {
"get": {
"summary": ".",
"operationId": "getNames",
"parameters": [
{
"name": "pageable",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/Pageable"
}
}
],
"responses": {
"200": {
"description": "List of names",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Pageable response"
}
}
}
}
}
}
}
}
}
Expected JSON (Different "path" value):
{
"openapi": "3.0.1",
"info": {
"title": "External API",
"description": "This set of API is used to serve external clients",
"version": "0.1"
},
"servers": [
{
"url": "https://api.xyz.net/",
"description": "Live"
}
],
"paths": {
"/v1/names": {
"get": {
"summary": ".",
"operationId": "getNames",
"parameters": [
{
"name": "pageable",
"in": "query",
"required": true,
"schema": {
"$ref": "#/components/schemas/Pageable"
}
}
],
"responses": {
"200": {
"description": "List of names",
"content": {
"*/*": {
"schema": {
"$ref": "#/components/schemas/Pageable response"
}
}
}
}
}
}
}
}
}
I have been trying to figure out any way to do this through some configuration or annotation, but not found anything yet.
Thanks in advance for your suggestions and help.
I am trying to add "Content-Disposition" header to my api response. This api downloads a file. Here is how I configured the json specification file for openapi-generator (for java spring):
"/download": {
"get": {
"description": "Returns the file",
"operationId": "getFile",
"responses": {
"200": {
"description":"A file",
"headers": {
"content-disposition": {
"description": "Content disposition header",
"schema": {
"type": "string",
"example": "attachment; filename=keyFile.pem"
}
}
},
"content": {
"application/octet-stream": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
},
"400": {
"description": "Delete operation not allowed"
},
"404": {
"description": "File not found"
}
}
}
}
But the code generated by openapi-generator does not add the header to the response. The swagger UI also does not show any header in the response.
The answer here says that adding headers is not supported in spring generator for openapi-generator. Is this true? If yes then, is there an alternative to this?
Can somebody help me with this? I am pretty new to spring-boot and open-api.
I'm having difficulty implementing a JSON to send as a POST call in Spring.
Which is the fastest and most effective way to turn this json into a java object or a map and make the call?
below is an example of a json to send:
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "edge-ws"
},
"spec": {
"selector": {
"matchLabels": {
"run": "edge-ws"
}
},
"replicas": 1,
"template": {
"metadata": {
"labels": {
"run": "edge-ws"
}
},
"spec": {
"containers": [
{
"name": "edge-ws",
"image": "server-tim:latest",
"imagePullPolicy": "Never",
"ports": [
{
"containerPort": 80
}
]
}
]
}
}
}
}
this and the second body that has a value (nodeport) that must be taken from a field entered by the user front end side.(page created in html)
{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
"name": "edge-ws",
"labels": {
"run": "edge-ws"
}
},
"spec": {
"type": "NodePort",
"ports": [
{
"port": 8080,
"targetPort": 80,
"nodePort": 30200,
"protocol": "TCP",
"name": "http"
}
],
"selector": {
"run": "edge-ws"
}
}
}
Both files must be sent with a single click on a button on the front end side.the first call with the first body starts and if everything is ok the second body starts
What should the class that maps objects look like? What should the controller look like instead?
They also gave me an address to call that can only be used on the machine, how can I test this call locally?
Thanks in advance!
You can use google's Gson library to convert the JsonString to Object and then use below code:
Gson gson = new Gson();
Object requestObject = gson.fromJson(jsonString, Object.class);
ResponseObject responseObject = restTemplate.postForObject(url, requestObject, ResponseObject.class);
I am trying to create one mapping.json under the mappings folder with multiple stubs as below. But I am facing the following error
Wiremock: v2.5.1 (standalone)
Mapping.json file looks,
[
{
"scenarioName": "Savings account Stub",
"request": {
"url": "/ws/*****",
"method": "POST",
"bodyPatterns" : [{
"contains" : "AccountRequest"
}
]
},
"response": {
"status": 200,
"bodyFileName": "******"
}
},
{
"scenarioName": "Current account Stub",
"request": {
"method": "POST",
"url": "/ws/*****",
"bodyPatterns": [
{
"contains": "AccountListRequest"
}
]
},
"response": {
"status": 200,
"bodyFileName": "******"
}
}]
Error:
Exception in thread "main" wiremock.com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.github.tomakehurst.wiremock.stubbing.StubMapping out of START_ARRAY token
Is there any possibility to create multiple stubs for the same URL in single mapping file? Can anyone tell me what is the exact issue?
Looking at the stubbing documentation, I think you want your mappings.json to look like...
{
"mappings": [
{
"scenarioName": "foo",
"request": {},
"response": {}
}, {
"request": {}
}
],
"importOptions": {
"duplicatePolicy": "IGNORE",
"deleteAllNotInImport": true
}
}
You'd then want to make a POST request to /__admin/mappings/import with your mappings.json as the request body. The reason for this is that I believe multiple mappings in a single file are only supported via the import option.
I need to get data from servlet when I pass schema like below.
attrServlet is servlet call.
{
"id": "../test#",
"$schema": "../schema#",
"title": "Test",
"type": "object",
"format":"grid",
"required": [
"/"
],
"properties": {
"/":
{
"title":"value",
"$ref": "http://00.00.00.00:8080/Test/attrServlet/#"
}
}
}
In the place of $ref, I need servlet data. My data coming through servlet into browser but on front end it's not reflecting. Any idea?