Search code examples
openapiopenapi-generatoropenapi-generator-maven-plugin

Initialize a variable to a new instance in Open API 3


I want to initialize the value of a List to a new ArrayList instead of the default null assignment. Is that possible?

I tried this :

Employee:
  type: array
  default: [ ]

What I get still in the code generated:

private List<Employee> employees= null;

what I want:

    private List<Employee> employees= new ArrayList(); //initialize to empty list every time, cannot be null to avoid NPE

Solution

  • Since you didn't specify which generator you are using, I'm going to assume the basic java generator (based on your java examples). However, these options can apply to nearly any generator.

    Option 1 - Required

    Marking the Arraylist as required in your schema will generate the following object.

    @Valid
    private List<@Valid Employee> employees = new ArrayList<>();
    

    Possibly unwanted effect

    Now that it is marked as required, the validation will fail any request that doesn't contain at least an empty employees object.

    Option 2 - Templating

    Update the mustache template to always initialize the list.

    1. Copy the pojo.mustache file to a location of your choosing and direct the generator to use the new templates folder.

    2. Change this line inside the isContainer check to read as follows:

    private {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}}{{#isArray}} = new ArrayList<>(){{/isArray}}{{/defaultValue}};
    

    Possibly unwanted effect

    Now every single arraylist that doesn't have a default value set will be initialized

    Option 3 - Extensions

    OpenAPI extensions are another viable option. These are similar to the templating option, except it allows you to define which fields get defaulted. The openapi-generator has a number of preconfigured extensions, but you can define your own as well. Here's how.

    1. Repeat the first step of Option 2 by setting up your templates.
    2. Change the same line mentioned above to read as follows (notice that use of the vendorExtensions value:
    private {{{datatypeWithEnum}}} {{name}}{{#defaultValue}} = {{{.}}}{{/defaultValue}}{{^defaultValue}}{{#vendorExtensions.x-is-default-array}} = new ArrayList<>(){{/vendorExtensions.x-is-default-array}}{{/defaultValue}};
    
    1. Add the extension to your Employees object definition in your yaml file
    Employees:
      type: array
      items:
        $ref: '#/components/schemas/Employee'
      x-is-default-array: true
    

    Possibly unwanted effect

    Doing this way will allow you to specifically identify which arrays you want to have a default. However, you will have to put the extension on every single array you want to have this default value. Additionally, if any users of your api are downloading your schemas, this will expose your schema's internal vender extensions (but not necessarily their usage).