1

In Rest response, the field which is marked as a "discriminator" in my swagger file is duplicated. I have a parent object which has a field called "subjectType" which I've marked as the discriminator. And in my rest call, I just return the resource object(either SubjectA object or SubjectB object based on subjectType in request) which has all the parameters mentioned in the below swagger file:

Subject:

type: object
discriminator: subjectType
properties:

  id:
    type: string
    minLength: 32
    maxLength: 32

  description:
    type: string
    maxLength: 350

  subjectType:
    type: string
    enum:
      - SubjectA
      - SubjectB

required:
  - subjectType
  - description

SubjectA:

allOf:

  - $ref: "#/definitions/Subject"
  - type: object
    properties:
      name:
        type: string
        maxLength: 100

      complexity:
        type: string
        maxLength: 256

    required:
    - name
    - complexity

SubjectB:

allOf:
  - $ref: "#/definitions/Subject"
  - type: object
    properties:
      prof:
        type: string
        maxLength: 100

      ref:
        type: string
        maxLength: 256

    required:
    - prof
    - ref

So, when I return the response object of type either SubjectA or SubjectB, the response object which I send back has only one "subjectType" field but the actual json response returned to the client(s) has two "subjectType" fields which I think swagger is doing it. Swagger Version: 2.4.1

Here's the response:

{ "subjectType" : "SubjectA", "id" : "123", "subjectType" : "SubjectA", "name" : "abc", "complexity" : "L1" }

@Path("/subjects")
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@ResponseStatus(status = Response.Status.CREATED)
public Response createSubject(Subject subject) {

        //Removed my DAO calls and other logic.

        final Subject subject =
                createSubject(profile); //Modifying the subject object in this method as per my needs.
        return Response.status(Response.Status.CREATED).entity(subject).build();


}

Here are the objects which got generated by swagger codegen:

@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaClientCodegen", date = "2019-04-01T17:05:27.110-07:00")@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "subjectType", visible = true )
@JsonSubTypes({
@JsonSubTypes.Type(value = SubjectA.class, name = "SubjectA"),
@JsonSubTypes.Type(value = SubjectB.class, name = "SubjectB"),
})

public class Subject {

@JsonProperty("id")
private String id;

@JsonProperty("description")
private String description;

@JsonProperty("subjectType")
private String subjectType;

//Getters and Setters

}


@javax.annotation.Generated(value = "io.swagger.codegen.languages.JavaClientCodegen", date = "2019-04-01T17:05:27.110-07:00")
public class SubjectA extends Subject {

@JsonProperty("name")
private String name;

@JsonProperty("complexity")
private String complexity;

//Getter and Setters


}

How I stop the subjectType field from populating twice in the Json response which is sent back to client(s)?

Anthon
  • 69,918
  • 32
  • 186
  • 246
AlfaRomeo
  • 35
  • 8
  • 1) You have `discriminator: type` but there's no `type` property in the Subject schema. Is it supposed to be `discriminator: subjectType`? 2) What library/framework do you use on the server side to produce the responses? Can you post the code of the endpoint that sends the problematic response? – Helen Apr 02 '19 at 07:48
  • @Helen 1. You're right discriminator is **subjectType** (it was a typo, I edited my question now). 2. We use Jersey(Jax-rs implementation). I have added the code snippets to my question now. Please check above. – AlfaRomeo Apr 02 '19 at 17:42
  • See if this helps: [Duplicate json property when converting java object to json string using jackson](https://stackoverflow.com/q/13262662/113116), [How to specify jackson to only use fields - preferably globally](https://stackoverflow.com/q/7105745/113116), [Duplicate JSON Field with Jackson](https://stackoverflow.com/q/18237222/113116) – Helen Apr 03 '19 at 08:28
  • 1
    Thanks helen, this post [Duplicate JSON Field with Jackson](https://stackoverflow.com/questions/18237222/duplicate-json-field-with-jackson) worked for me. I had change my @JsonTypeInfo annotation to JsonTypeInfo.As.EXISTING_PROPERTY instead of JsonTypeInfo.As.PROPERTY. – AlfaRomeo Apr 08 '19 at 20:27
  • @AlfaRomeo Do you use the generated class and change it every time after it is newly generated? – hellectronic May 15 '19 at 13:20

1 Answers1

-1

I am not entirely sure what your concern is, having duplicate keys in the repsonse JSON, apart from the overhead involved.

The JSON RFC, says about JSON objects:

The names within an object SHOULD be unique.

And the SHOULD within that is formally defined as

This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

Now there might not be a reason given that this duplication happens, but it is not forbidden, and therefor all confirming JSON tools need to be able to deal with it. I would have expected that the JSON specification says what value to select in case there are non-unique keys (e.g. the first, or the last value), but since the values for those keys are the same it doesn't really matter.

That still leaves the question how this happens. In many languages the internal representation of a JSON object (e.g. dict in Python) are hash based maps, that don't even can have duplicate keys. I assume this JSON gets generated on-the-fly in some way, without having a full internal representation, which would filter out the duplicates.

Community
  • 1
  • 1
Anthon
  • 69,918
  • 32
  • 186
  • 246
  • While this answer has useful info, it does not really address the question which seems to be "how to change my code / configure my server to not produce duplicate JSON fields". – Helen Apr 02 '19 at 07:58
  • @Anthon I have attached the code snippets to my original question. The response which I send back from my controller has only one subjectType field as I just return back **subject** object which just has one subjectType field. But the json response returned to the client has two **subjectType** fields. There is no way my controller returns the duplicate field since it just has one subjectType field in Subject object. I have also debugged through my code and noticed only one subjectType field is being returned. I am not able to understand how this field is getting duplicated in json response. – AlfaRomeo Apr 03 '19 at 00:48
  • @AlfaRomeo Welcome to [so]. There are a few things you should not do on this site, one of them is changing a question on the fly. I addressed the concern in your original post, but now you changed the question so my answer only makes sense if someone reviews the history of your question. You should never change a question like that, better to post a new one referring to this one: "In my question here I learned that double keys in JSON file are not important, but I still would like to now how to prevent that from happening. Here is my code....". You should not put "Appreciate ...." in a post. – Anthon Apr 03 '19 at 06:32
  • 1
    @AlfaRomeo To clarify further: if there is no answer yet to your original post, and you then realise the original questions will not get you the answer you want (because you reread your interrogative sentences, or because of comments under your post, etc), then you can of course change your post to clarify what you need. But you should always be aware that you don't create a moving target after the question in your original post has been answered. – Anthon Apr 03 '19 at 06:44
  • 1
    Note that you can and should rollback question edits that change the question in a way that invalidates answers, and flag for moderator attention if this results in a rollback war. – Ryan M Apr 08 '22 at 10:11