Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot substitute a model with "string" #2969

Open
hosswald opened this issue Sep 27, 2018 · 3 comments
Open

Cannot substitute a model with "string" #2969

hosswald opened this issue Sep 27, 2018 · 3 comments

Comments

@hosswald
Copy link

hosswald commented Sep 27, 2018

I have a model class that can appear as a @PathParam, @QueryParam or inside complex response and request objects.
The class uses custom serialization:

@Schema(type = "string")
@JsonSerialize(using = UserIdentitySerializer.class)
@JsonDeserialize(using = UserIdentityDeserializer.class)
@JsonFormat(shape = JsonFormat.Shape.STRING)
public class UserIdentity {
    String email;
    String id;
}

plus a custom javax.ws.rs.ext.ParamConverterProvider.
The serializer/deserializer converts it from/to a string, meaning that a userIdentity can be either an ID or an email. It works.

Unfortunately, I can't get swagger-core to generate an API documentation that lists fields/parameters of type UserIdentity as being strings actually.
Instead, I get:

        "parameters" : [ {
          "name" : "userIdentity",
          "in" : "query",
          "schema" : {
            "$ref" : "#/components/schemas/UserIdentity"
          }
        }

and

      "UserIdentity" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "string"
          },
          "email" : {
            "type" : "string"
          }
        }
      }

Is there a way to get an output like this?

        "parameters" : [ {
          "name" : "userIdentity",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }

and no model generated for UserIdentity?
Alternatively a model for UserIdentity that makes it clear that it is actually just a string?

@frantuma
Copy link
Member

frantuma commented Oct 8, 2018

Assuming from the code you shared, that you're using userIdentity (also?) as a query parameter for an operation, the following will have that parameter resolved as string:

            @Parameter(
                    in = ParameterIn.QUERY,
                    schema = @Schema(type = "string")
            ) UserIdentity userIdentity

usage both in parameter and e.g as property could be implemented as in example below:

@Path("/test2969")
public class Ticket2969Resource
{
    @Produces({ MediaType.APPLICATION_JSON })
    @GET
    public Test test2969(
            @QueryParam("userIdentity")
            @Parameter(
                    in = ParameterIn.QUERY,
                    schema = @Schema(type = "string")
            ) UserIdentity userIdentity) {
        return null;
    }

    public class Test {
        public UserIdentity userIdentity;
    }

    @Schema(type = "string")
    @JsonSerialize(using = UserIdentitySerializer.class)
    @JsonDeserialize(using = UserIdentityDeserializer.class)
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    public class UserIdentity {
        String email;
        String id;

        public UserIdentity(String val) {
            email = val;
        }
    }
}

which produces the following output:

openapi: 3.0.1
paths:
  /test2969:
    get:
      operationId: test2969
      parameters:
      - name: userIdentity
        in: query
        schema:
          type: string
      responses:
        default:
          description: default response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Test'
components:
  schemas:
    Test:
      type: object
      properties:
        userIdentity:
          type: string

please close ticket is this solves your issue

@hosswald
Copy link
Author

hosswald commented Oct 8, 2018

@frantuma thank you, it works (leaving out in = ParameterIn.PATH because it seems to be automatically correctly deduced from the @PathParam annotation).
However, it is a bit tedious and error-prone to have to add another annotation to each parameter of type UserIdentity, and it would be great if the per-parameter annotation could be replaced by a global construct. Maybe just use the annotation on UserIdentity as a default for parameters, too. If necessary, being able to override the default by using typeParam, typeField etc, if that's feasibly.

@ktalebian
Copy link

@frantuma I opened a new issue #3389 with a slightly different example. I want to substitute one of the fields of my object. So for example, if the email's field of UserIdentity was a different type, I want to substitute that to be of type String.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants