Skip to content

Optional properties using Jackson2 #183

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

Merged
merged 1 commit into from
Sep 28, 2017
Merged

Conversation

vojtechhabarta
Copy link
Owner

This PR is continuation of #179, thanks @Yona-Appletree for feature request and first implementation.

This PR adds optionalProperties parameter with allowed values useSpecifiedAnnotations, useLibraryDefinition and all.

It also changes how Jackson2 modules are treated, this is incompatible change, please see details below.

Optional Properties

1. optionalProperties = useSpecifiedAnnotations

Let's say we want to generate following TypeScript interface:

interface Person {
    name: string;  // required
    age?: number;  // optional
}

We can do this with this configuration:

<configuration>
    <optionalProperties>useSpecifiedAnnotations</optionalProperties>
    <optionalAnnotations>
        <annotation>javax.annotation.Nullable</annotation>
    </optionalAnnotations>
</configuration>

and Java class:

public class Person {
    public String name;
    @Nullable
    public int age;
}

This was already possible and it is still default behavior.

2. optionalProperties = useLibraryDefinition

With this new feature we can leverage Jackson2 to determine which properties are optional and which required. Then it is possible to use Jackson2 annotations, JAXB annotations or even Kotlin nullable types to specify property optionality.

Jackson2 library

Following configuration:

<configuration>
    <jsonLibrary>jackson2</jsonLibrary>
    <optionalProperties>useLibraryDefinition</optionalProperties>
</configuration>

allows us to use @JsonProperty to specify optionality:

public class Person {
    @JsonProperty(required = true)
    public String name;
    @JsonProperty(required = false)
    public int age;
}

JAXB library

Similarly for JAXB. Configuration:

<configuration>
    <jsonLibrary>jaxb</jsonLibrary>
    <optionalProperties>useLibraryDefinition</optionalProperties>
</configuration>

class:

public class Person {
    @XmlElement(required = true)
    public String name;
    @XmlElement(required = false)
    public int age;
}

Kotlin nullable types

Jackson2 provides KotlinModule which makes nullable types accessible to typescript-generator.
This module can be configured using this snippet:

<configuration>
    <jsonLibrary>jackson2</jsonLibrary>
    <optionalProperties>useLibraryDefinition</optionalProperties>
    <jackson2Modules>
        <module>com.fasterxml.jackson.module.kotlin.KotlinModule</module>
    </jackson2Modules>
</configuration>

Then we can write Kotlin data class like this:

data class Person(
        val name: String,
        val age: Int? = null
)

and typescript-generator will know from Jackson2 which properties are required/optional.

3. optionalProperties = all

This makes all properties optional. This setting have same effect as declarePropertiesAsOptional parameter (which is now deprecated).

Jackson2 modules

Before this PR typescript-generator by default loaded all Jackson2 modules automatically. This automatic module discovery relies on module presence on classpath which is relatively fragile mechanism and for example JaxbAnnotationModule currently breaks @JsonProperty.required functionality.

So now typescript-generator by default loads no modules. Previous behavior can be turned on using jackson2ModuleDiscovery parameter. Individual modules can be specified using jackson2Modules parameter (recommended way). Old disableJackson2ModuleDiscovery parameter is effectively removed.

@Yona-Appletree
Copy link
Contributor

This looks great, thanks. I've tested it on my Kotlin project and everything seems to work as expected.

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

Successfully merging this pull request may close these issues.

2 participants