When building MuleSoft API’s, RAML is the starting point. It is from here that we design our API structure and it is from here that we generate our initial Mule Flows. 

 

Handling null Values

There is a plethora of RAML tutorials out there, both within and outside of the Mule context. I won’t bother you with the basics that any developer can find out for themselves.

However, there are a few interesting scenarios that can emerge. For instance, null values in a payload.

When calls from an API consumer failed against a particular API,  they called me in to see why. The calls were pretty standard but for the fact that they omitted one optional field in the request. I simulated a request, removed the optional field and all worked. Futher investigation revealed that they were actually sending the field with a null value.

In other words, a call with optionalField set to null…

{
   "requiredId": "12345",
   "requiredStatus": "In Progress",
   "optionalField": null
}

… failed, but…

{
  "requiredId": "12345",
  "requiredStatus": "In Progress",
}

… omitting the field entirely, worked as expected. After all, it is optional.

When the API Consumer’s developer showed me the failed request, he graciously offered to fix it on his side, and remove the field altogether, if null. However, I felt that the request was valid JSON and, as such, should be supported by the MuleSoft API. In fact, I assumed that the issue must be somewhere in the application’s code and that a simple null handler in Dataweave would solve the problem.

Only when I looked at the code, did I realise that was not the case. In fact, APIKit was rejecting the message on the basis that the field had been defined as a String in the RAML. As such, it would not accept a null value and responded with  a Bad Request before any of the application’s code could get a hold of it. The problem was in the RAML file itself.

Solution

The solution was, in fact, quite simple.

By adding an additional type — nil —  to the acceptable values list for the optional field, we made the API a little more robust:

type: string | nil

Here is a comprehensive version of the RAML…

types:
   apiRequest:
      type: object
      description: Basic request to invoke the API
      properties:
         requiredId:
            type: string
            required: true
            description: "Unique identifier for the application to be updated."
            example: "12345"
        requiredStatus:
           type: string
           required: true
           description: "Status to which process should be set."
           example: "In progress"
        optionalField:
           type: string | nil
           required: false
           description: "Optional reference provided by API consumer."
           example: "56789"
   apiResponse:
      type: object
      description: Response structure for an API Update request
      properties:
         status:
         type: string
         enum: ["Accepted","Rejected"]
         required: true
         description: "Response status."
         example: "Accepted"
/api:
   /invoke:
      post:
         description: "Initiate approval for a given application by specifying api_id and contract_id."
         body:
            application/json:
            type: apiRequest
         responses:
            200:
               body:
                  application/json:
                     type: apiResponse

 

As is often the case, this API development team had a choice; take the easy way out or to go the extra mile and make the API more robust.

It might have been easier to accept the external team’s offer and get them to resolve the issue (i.e. come in line with the existing API definition). However, that would only work until the next time an API consumer sent a null value in the optional field. And that team might be less forgiving. That team might be more inclined to stand on principle and assert that their request is valid and that the API should support it. That team would be right!

 And no self-respecting Mule Whisperer would force every API consumer to come in line with a brittle API when six characters (including spaces) in a RAML file will resolve the issue once and for all.  

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>