Handling null attributes in a generated Java client library

875 views
Skip to first unread message

Mark Spielman

unread,
Oct 19, 2015, 2:29:17 PM10/19/15
to Swagger

I am relatively new to swagger but I’m trying to use it to model a new REST API we are creating. I have an API specified in Swagger 2.0. I’ve then used the Swagger Editor to generate a client library in Java and I’m using the Node.js “Swagger Express Middleware” to create a mocking server based on my schema. I have then turned to Java and attempted to send a POST request to the back end. What I’m seeing is that all the attributes that I do not specify in Java are being sent as null. This is causing a parse failure on the JSON validation at the Node.JS server.

 

For example – Here is some Java code:

 

public class QueuesTest

{

       private static DefaultApi apiClient;

       private String C_MSG_VPN = "default";

      

       @BeforeClass

       public static void initApi() {

              apiClient = new DefaultApi();

              apiClient.getApiClient().setBasePath("http://192.168.1.110:8081/v1");

       }

   

 

    @Test

    public void testSimpleQueueCRUD() throws ApiException

    {

       String queueName = "Q/test/queue";

       MessageSpoolQueue queueToCreate = new MessageSpoolQueue();

       queueToCreate.setName(queueName);

       queueToCreate.setMaxSpoolUsage("3000");

       queueToCreate.setAccessType(AccessTypeEnum.EXCLUSIVE);

       queueToCreate.setConsumerAckPropagation(false);

      

       MessageSpoolQueue createResponseapiClient.messageVpnsVpnNameMessageSpoolQueuesPost(queueToCreate, C_MSG_VPN);

      

       assertNotNull(createResponse);

       assertEquals(queueToCreate, createResponse);

       assertEquals(queueName, createResponse.getName());

      

      

       List<MessageSpoolQueue> responseapiClient.messageVpnsVpnNameMessageSpoolQueuesGet(C_MSG_VPN);

      

        assertNotNull(response);

    }

}

 

My swagger.json definition for this object is:

 

  messageSpoolQueue:

    example:

      accessType: exclusive

      consumerAckPropagation: true

      name: exampleQueue

    properties:

      accessType:

        enum:

          - exclusive

          - non-exclusive

        type: string

      consumerAckPropagation:

        type: boolean

      event:

        $ref: '#/definitions/messageSpoolQueueEvent'

      maxSpoolUsage:

        type: string

      name:

        description: ID of the queue.

        type: string

      owner:

        type: string

      maxBindCount:

        type: string

      ...{removed extra attributes for brevity}...

 

    type: object

 

In the above, I didn’t specify “owner” or “maxBindCount” in the Java unit test. The node.js server reports the following:

 

 

  swagger:middleware POST /v1/messageVpns/default/messageSpool/queues matches Swagger path /messageVpns/{vpnName}/messageSpool/queues +0ms

  swagger:middleware Parsing 2 request parameters... +17ms

  swagger:middleware     Parsing the "body" body parameter +0ms

Error: The "body" body parameter is invalid ({"accessType":"exclusive","consumerAckPropagation":false,"event":null,"maxBindCount":null,"maxDeliveredUnackedMsgsPerFlow":null,"maxMessageSize":null,"maxRedelivery":null,"maxSpoolUsage":"3000","maxTtl":null,"name":"Q/test/queue","owner":null,"permission":null,"rejectLowPriorityMsg":null,"rejectLowPriorityMsgLimit":null,"rejectMsgToSenderOnDiscard":null,"respectTtl":null,"shutdown":null,"vpnName":null})

Data path: "/maxBindCount"

Schema path: "/properties/maxBindCount/type"

Invalid type: null (expected string)

    at ono (/home/demo/sempv2MockServer/node_modules/swagger-express-middleware/node_modules/ono/lib/index.js:62:17)

    at parseParameter (/home/demo/sempv2MockServer/node_modules/swagger-express-middleware/lib/param-parser.js:146:11)

    at /home/demo/sempv2MockServer/node_modules/swagger-express-middleware/lib/param-parser.js:93:18

    at Array.some (native)

    at parseBodyParam (/home/demo/sempv2MockServer/node_modules/swagger-express-middleware/lib/param-parser.js:77:10)

    at Layer.handle [as handle_request] (/home/demo/sempv2MockServer/node_modules/express/lib/router/layer.js:95:5)

    at trim_prefix (/home/demo/sempv2MockServer/node_modules/express/lib/router/index.js:312:13)

    at /home/demo/sempv2MockServer/node_modules/express/lib/router/index.js:280:7

    at Function.process_params (/home/demo/sempv2MockServer/node_modules/express/lib/router/index.js:330:12)

    at next (/home/demo/sempv2MockServer/node_modules/express/lib/router/index.js:271:10)

 

 

Based on some searching, I believe I’d like to figure out a way to make use of the JsonSerialize markup for non-null. (@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)  But I can’t quite figure out is how to do this from Swagger so that the Java client libraries would just auto generate correctly. Is there some markup I’m missing in my Swagger definition? Or am I totally off in the wrong path here?

 

Any help would be greatly appreciated.

 

Thanks

Mark

 

tony tam

unread,
Oct 19, 2015, 2:39:59 PM10/19/15
to Swagger
Looks like you should edit the JSON.java to add the Jackson Serialization option that you mentioned.  This file is generated in the client library.

Mark Spielman

unread,
Oct 19, 2015, 4:28:36 PM10/19/15
to Swagger
Thank you for your response Tony. You are correct. If I update the constructor of the JSON class with:
   
  mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

I can work around the issue. Is there any way in my Swagger schema I can trigger this in the client code generation? What I'd like is to design a swagger schema that would work by default with generated client libraries. One option I suppose is to update our server and schema to be more tolerant of nulls but I'd prefer to solve this in the schema. How do other people deal with this?

Thanks
Mark

tony tam

unread,
Oct 19, 2015, 6:17:28 PM10/19/15
to Swagger
Hi Mark, you have some options, the easiest being to modify the templates for the client codegen and passing `-t path/to/your/templates` when generating.

Mark Spielman

unread,
Oct 19, 2015, 7:08:32 PM10/19/15
to Swagger
Excellent I will try that. Is there any reason this is not set by default
in the provided templates from swagger? I'd just like to understand a bit
more about typical usage etc.

tony tam

unread,
Oct 19, 2015, 10:21:34 PM10/19/15
to Swagger
Good question.  It may be correct to do this by default--please follow this ticket:

Mark Spielman

unread,
Oct 19, 2015, 10:35:20 PM10/19/15
to Swagger
Thank you Tony. I will track the issue and appreciate your answers.

wing328

unread,
Oct 21, 2015, 7:02:57 AM10/21/15
to Swagger
Hi Mark,

@xhh has submitted a PR, which has been merged into the master. Can you please pull the latest swagger-codegen to confirm if the issue has gone?

Thanks,
William

Mark Spielman於 2015年10月20日星期二 UTC+8上午10時35分20秒寫道:

Mark Spielman

unread,
Oct 21, 2015, 12:11:35 PM10/21/15
to Swagger
This morning I was able to pull the latest and validate that this resolves my issue. So thank you very much!

Mark

William Cheng

unread,
Oct 21, 2015, 12:17:24 PM10/21/15
to swagger-sw...@googlegroups.com
No problem. Glad to hear that it's resolved. If you've any feedback on the API client, please let us know.

William

--
You received this message because you are subscribed to a topic in the Google Groups "Swagger" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/swagger-swaggersocket/EnEURydhPZA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mark Spielman

unread,
Oct 21, 2015, 12:34:30 PM10/21/15
to Swagger
Perfect. Will do!
Reply all
Reply to author
Forward
0 new messages