Using specific properties while referencing to schema - swagger

I'm using swagger 2.0 and I have the following schema(definition) :
"User": {
"type": "object",
"properties": {
"firstName": {
"type": "string",
"example": "Tom"
},
"lastName": {
"type": "string",
"example": "Hanks"
},
"email": {
"type": "string",
"example": "Tom.Hanks#gmail.com"
},
"password": {
"type": "string",
"example": "azerty#123456"
}
}
and i want to refer to this schema in one of my responses, so i do the following:
"responses": {
"201": {
"description": "Created.",
"schema": {
"$ref": "#/definitions/User"
}
}
}
Until now everything works perfectly, but i don't want to expose the password property in the response schema. is the anyway to choose exactly the properties i want to use from the Userdefinition ?

No, there is no way. I'd suggest you define 2 types:
One type for user data without password, let's name it User.
And another type that inherits from it and contains additionally a password attribute. Let's name it UserWithCredential.

Related

openapi scheme generated does not contains "content" of EntityModel spring-hateoas entities

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.

Pass argument to `$ref` in OpenAPI 3

Assume I have following schema to reuse later using $ref:
"schemas": {
"Order": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"petId": {
"type": "integer",
"format": "int64"
}
}
}
But I have another schema similar to this:
"schemas": {
"Order": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"itemId": {
"type": "integer",
"format": "int64"
}
}
}
Only difference between them is itemId and petId, I want to create only one schema and pass itemId or petId when referencing.
How to accomplish this? Are there any alternative solutions?
There's no way to pass arguments along a schema reference, really.
What we could do in your case is to have a base Order schema with just the common properties, and then separate schemas for petId/itemId Orders that utilize allOf.
Check this answer for another example (or this for a more concrete one!).

Can we refer to a only one property of other schema

I have a rest service, that can work as below:
http://server/path/AddressResource and
http://server/path/AddressResource/someAnotherPath
I have a definitions like below.
"definitions": {
"address": {
"type": "object",
"properties": {
"street_address": { "type": "string" },
"city": { "type": "string" },
"state": { "type": "string" }
},
"required": ["street_address", "city", "state"]
}
}
that is the response of path1, and in path two i just want to return the "city" property of address.
Can I create a schema, referring to address and using just one of it's property?

Swagger/Swashbuckle showing "Unknown response type"

I am creating an C# ASP.NET Core 2.0 REST API, all going well for the most part. It is using MVC routing to gen the REST API. The controllers are pretty simple.
// POST: api/Volume/{zoneID}/Set/{volume}
[HttpPost("{zoneId:int}/[action]/{volume:int}", Name = "Set")]
public IActionResult Set(int zoneId, int volume)
{
return CreateAndSend(strZonesLevel, zoneId, $"{volume:X2}");
}
Using the latest of everything, installed Swagger/Swashbuckle for AspNetCore 2.3.0 and the UI comes up with the APIs and all. The SwashBuckle UI works well, I can test the API etc.
The one exception is that on the UI, the Response type ALWAYS comes back as "Unknown Response Type."
https://i.stack.imgur.com/6qqBh.jpg
I have the following attributes in front of my class (all methods return the same type)
[Produces("application/json")]
[Route("api/Volume")]
[ProducesResponseType(typeof(ControllerResponseModel), 200)]
[ProducesResponseType(typeof(ControllerResponseModel), 400)]
[ProducesResponseType(typeof(ControllerResponseModel), 500)]
The generated JSON seems allright, the ControllerResponseModel is in the definition, and referenced in all the right places by the Volume API. Here is a subset.
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "AVController API"
},
"paths": {
"/api/Volume/{zoneId}/Set/{volume}": {
"post": {
"tags": ["Volume"],
"operationId": "ApiVolumeByZoneIdSetByVolumePost",
"consumes": [],
"produces": ["application/json"],
"parameters": [
{
"name": "zoneId",
"in": "path",
"required": true,
"type": "integer",
"format": "int32"
},
{
"name": "volume",
"in": "path",
"required": true,
"type": "integer",
"format": "int32"
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
},
"400": {
"description": "Bad Request",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
},
"500": {
"description": "Server Error",
"schema": {
"type": "array",
"items": { "$ref": "#/definitions/ControllerResponseModel" }
}
}
}
}
}
},
"definitions": {
"ControllerResponseModel": {
"type": "object",
"properties": {
"command": { "type": "string" },
"message": { "type": "string" },
"url": { "type": "string" }
}
}
}
}
Any ideas why the UI would not be showing the return type and value? I have tried numerous things, like using gets instead of posts as well as using the [SwaggerResponse] attributes, but the results are the same.
This has been identified as an Edge browser issue with Swashbuckle, not the code posted here. It is reproducible on many sites. Issue has posted on GitHub # https://github.com/swagger-api/swagger-ui/issues/4337

How can I describe complex json model in swagger

I'm trying to use Swagger to describe web-api I'm building.
The problem is that I can't understand how to describe complex json object?
For example, how to describe this objects:
{
name: "Jhon",
address: [
{
type: "home",
line1: "1st street"
},
{
type: "office",
line1: "2nd street"
}
]
}
Okay, so based on the comments above, you want the following schema:
{
"definitions": {
"user": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": {
"type": "string"
},
"address": {
"type": "array",
"items": {
"$ref": "#/definitions/address"
}
}
}
},
"address": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [ "home", "office" ]
},
"line1": {
"type": "string"
}
}
}
}
}
I've made a few assumptions to make the sample a bit more complicated, to help in the future.
For the "user" object, I've declared that the "name" field is mandatory. If, for example, you also need the address to be mandatory, you can change the definition to "required": [ "name", "address" ].
We basically use a subset of json-schema to describe the models. Of course not everyone knows it, but it's fairly simple to learn and use.
For the address type you can see I also set the limit to two options - either home or office. You can add anything to that list, or remove the "enum" entirely to remove that constraint.
When the "type" of a property is "array", you need to accompany it with "items" which declares the internal type of the array. In this case, I referenced another definition, but that definition could have been inline as well. It's normally easier to maintain that way, especially if you need the "address" definition alone or within other models.
As requested, the inline version:
{
"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"
}
}
}
}
}
}
}
}

Resources