I have just a restrul api(I cant add swagger doc to my api) and my json data model shcema.
I want to be able to generate a client based on my json data model schema so I can talk to my restful api from my app.
How can you generate swagger client routes based on shema?
Say I have such simple schema:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"house": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "number"
},
"type": {
"type": "string"
}
}
}
}
}
}
how can I generate/add get/put/delete swagger routes to my schema so then I can generate a proper client for my restful api?
Related
I am facing a strange issue that I extract a schema of api response and added json file in my serenity project. While validating schema, what ever the schema provided the test was passing, moreover if I changed any type of key like I change the data-type of any key value correct schema( like changed the name data-type from string to integer) then test failed.
Scenario:
My API response:
{
"name":"Alex",
"age" : 20,
"city":"New York"
}
My Schema for this API: Test Passed which is ok
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer"
},
"city": {
"type": "string"
}
},
"required": [
"name",
"age",
"city"
]
}
If I changed the schema from correct to wrong that is remove any key value pair the test even passed which is not correct
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"city": {
"type": "string"
}
},
"required": [
"name",
"city"
]
}
Moreover if I write only " { } " in the Schema file the test passed
The method I am using for validation is matchesJsonSchemaInClassPath
The schema validation only checks the data-types that are coming for values in JSON are correct by matching with schema. For the data validation there is another method in Serenity BDD that is VerifyResponseData.ofTheresponse(jsonobj)
This works for me
I'm using :
springdoc-openapi-ui : 1.6.6
springdoc-openapi-hateoas: 1.6.8
swagger-models: 2.1.12
spring-hateoas: 1.4.1
When i retrieve the generated openapi scheme from my rest services i get responses format for hateoas EntityModel withtout the content section. (v3/api-doc endpoint)
Is there a way to get the scheme generated with the content section ?
I get :
{
"EntityModelProject": {
"required": [
"name"
],
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"pattern": "[a-zA-Z0-9-_]*",
"type": "string"
},
"label": {
"type": "string"
},
"links": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
I would like to have :
{
"EntityModelProject": {
"type": "object",
"properties": {
"content": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Project"
}
},
"links": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}
EDIT 1 :
After looking into spring-hateoas code i see that the EntitModel class contains the Jakson #JsonUnwrapped annotation on getContent method. In our project we use Gson and Nt jakson. With Gson serialization, the result containts de "content" section. Wtih jakson the content section is unwrap. I assume that, the scheme generated by springdoc-openapi interpret with jsackson and not gson.
EDIT 2 :
Indeed, the ModelResolver class of io.swagger.v3.core.jackson, read Jackson annotations to create schema. In my case, the #JsonUnwrapped annotation. Swagger schema generation seems to be not compatible with Gson formatted api.
I get the following error when creating API in Postman: "Invalid data type. Must be either, array, boolean, integer, number, object or string"
The error is fixed when converting the line "type": "file" to "type": "object", but I am not sure if there is a proper way for this situation. Because with this update, the request may not be passed when sending request in Postman.
"parameters": [
{
"in": "body",
"name": "file",
"description": "file",
"required": false,
"schema": {
"type": "array",
"items": {
"type": "file"
}
}
},
...
]
So, how can I fix the problem in Postman?
The problem is not with Postman, but with the API definition. "type": "file" is not a valid type value for use in schemas and body parameters, this type can only be used in in: formData parameters.
On the other hand, I do not add file while trying to test my app via Postman. For this reason, I just want to suppress the errors
In this case you could change "type": "file" to "type": "string" to suppress import errors. Or remove the entire problematic operation from the API definition.
How to properly define file uploads in OpenAPI
The API definition is trying to describe uploading of a file array - but this is not supported in OpenAPI 2.0 (swagger: '2.0'). OAS2 only supports upload of individual named files via multipart/form-data, in which case the API definition would look like this:
{
"swagger: "2.0",
...
"paths": {
"/something": {
"post": {
"consumes": [
"multipart/form-data"
],
"parameters": [
{
"in": "formData",
"name": "file1",
"type": "file" // A single file sent via form field "file1"
},
{
"in": "formData",
"name": "file2",
"type": "file" // Another file sent via form field "file2"
}
]
...
}
Uploading an array of files is supported in OpenAPI 3 though:
{
"openapi": "3.0.0",
...
"paths": {
"/something": {
"post": {
"requestBody": {
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"properties": {
"file": {
"type": "array",
"items": {
"type": "string",
"format": "binary"
}
}
}
}
}
}
},
...
}
}
}
}
I have the following OpenAPI 3 schema:
{
...,
"components": {
"schemas": {
"User": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"readOnly": true
},
"name": {
"type": "string"
}
}
},
"Report": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64",
"readOnly": true
},
"user": {
"$ref": "#/components/schemas/User"
}
}
}
}
}
}
Now, if I specify the GET requests for both User and Report everything looks good. The POST request for User is also working. However, the POST request for Report does not work. The body for the Report POST request should look like this:
{
"user": {
"id": 1
}
}
So the "name" property should not be specified since it is only a reference to a user that already exists and will be matched based on the id.
Is it possible to write the Report POST request so it understands that only the id of the user should be specified? Or am I forced to create two different Report schemas, one for the GET request and one for the POST request?
There are a couple ways you can approach this problem. You can either create a definition exclusively for POST, or split your User definition into more atomic components for reuse.
Option 1: Multiple Definitions
Construct your Report user definition to something like this:
"user": {
"id": {
"type": "integer",
"format": "int64",
"readOnly": true
}
}
This has the benefit of being quick and easy, with no impact on other areas of your defnition. But this lends itself to a lot of code duplication, and any future changes to your design will require you to make sure you don't miss any of these special definitions.
Option 2: Split and Reuse Your Definitions
You have a two distinct properties that have different uses, that are used in multiple definitions. This is a good candidate for a ref. Split up your User definition into multiple schemas. Something like this:
"schemas": {
"userId": {
"type": "integer",
"format": "int64",
"readOnly": true
},
"userName": {
"type": "string"
},
"User": {
"type": "object",
"properties": {
"id": {
"$ref": "#/components/schemas/userId"
},
"name": {
"$ref": "#/components/schemas/userName"
}
}
}
This allows you to reuse the userId in your Report with the same definition of what an id actually is. This approach can start getting hard to read as you start growing your definitions into a larger API, but is far more maintainable as your API changes shape over time. Note that this also helps to define the difference between a User ID and a Report ID, which, while sharing the same name, likely hold different data and may have divergent rules over time.
We are using Swagger 2.0 for our documentation. We are Pro-grammatically creating swagger 2.0 spec straight out our data design documents.
Our Model is very complex and nested. I would like to understand can we define nested array objects defined inline.
for e.g :
{
"definitions": {
"user": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["home",
"office"]
},
"line1": {
"type": "string"
}
},
"Person": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}
}
}
}
We have many cases where we encounter this in our model and defining a #ref is not an option that we want to consider at this time. We need this to handled inline.
As per the following post : https://github.com/swagger-api/swagger-editor/issues/603#evenenter code heret-391465196 looks like its not supported to handle nested array objects defined inline.
Since lot of big enterprise's have a very complex data model we would like to have this this feature to be supported in swagger 2.0 spec.
Is there any thought on this feature to be added.
You document is just invalid and this is not about nested arrays: the property Person is not allowed in a Swagger 2.0 schema inside items.
The only allowed properties in a schema are: $ref, format, title, description, default, multipleOf, maximum, exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern, maxItems, minItems, uniqueItems, maxProperties, minProperties, required, enum, additionalProperties, type, items, allOf, properties, discriminator, readOnly, xml, externalDocs, example.