Presently I am using swagger codegen tool to convert a RAML definition into swagger format and generating java client from this format. This gives me POJOs for all the data types mentioned in the RAML. Every time I change some data field in the RAML types, I have to regenerate the POJOs and all the code implementation in service layers has to be rewritten. It is becoming very cumbersome to repeatedly do the same things.
I am thinking if only these POJOs were generated with builder pattern, like,
mydataobject.builder.addfield1(10).addfield2(2);
it will greatly help me keep the code in service layer untouched.
Is there a way to auto-generate pojos that have builder methods in them?
You can use Lombok for that.
#lombok.Builder// Builder companion class, and static method
#lombok.Value // Getters, setters, and contructors
class Pojo {
String value;
Number number;
}
Which gives you this code:
final Pojo pojo = Pojo.builder()
.value("foo")
.number(100)
.build();
You have to proceed your generated code in order to add this annotations, see Add lombok (or any) annotation to swagger generated class for discussion of that.
Related
In one of my projects, I'm handling some POJOs that may have 20+ fields. I'm using the Builder Pattern to make object creation less cumbersome. Lombok's #Builder annotation really removes a lot of boilerplate code and speeds up my process. Thing is that I want to add Javadoc to the 'setter'-like methods in the various builders of my project. I've tried to put the Javadoc to the fields just like Lombok's recommendation on #Getter/#Setter but it doesn't seem to work. Is there any possible method to achieve what I want?
You can also use #Accessors(chain = true) instead of #Builder.
Your Getter and Setter will return your instance and you can also use Method-Chaining like in Builder Pattern.
The syntax will be like
Model model = new Model().setId(23L).setTitle("test");
We always use this instead of #Builder.
Lomboks recommendation should work with this solution
I am working on a project that has a fair amount of data objects that use a "fluent interface" or "method chaining" on their setters so all of the setters in each data object return this. I have looked around and found this question, but it is unclear to me whether this can be used with Yaml as the annotations specifically mention JSON, and also this seems to enable mapping to objects using an actual builder pattern, which is a little different. The project is currently using SnakeYaml, but that can be tossed away if some other lib like Jackson can do this.
It turns out that this is in fact possible. Jackson supports yaml and will work with builder style setters by default without any extra configuration.
I need to make a DTO class that represents a JSON request body.
I’d like to make it fully immutable with final fields. I’ve already seen implementations based on #JSONCreator all args constructor but I also require one more feature.
The DTO class should be flexible and tolerate some missing fields in a request meanwhile ensure that all necessary properties are in-place.
Could you provide me an example of such DTO, please?
Jackson will automatically handle missing fields and just set those fields to null.
It also has some configuration options on whether when serializing responses, null fields should be omitted or set to the special value null.
objectMapper.setSerializationInclusion(Include.NON_NULL);
On another note, if you are designing an API, you might want to look at Swagger / OpenAPI and define your API declaratively from there (you can specify whether a field is optional or required). Then use the codegen tools to automaticlly generate your DTOs. (They will follow the best patterns and also offer Fluent API style setters).
As #jbx pointed out that Jackson automatically handles missing fields and sets it to null.
If you want to ensure that required fields are populated, you need to mark those as #javax.annotation.Nonnull or lombok.NonNull.
Using this Jackson throws a NullPointerException if that field in null while de-serialization of request to DTO class.
I am trying to use Swagger to document a Spring-MVC based REST-API and am having problems getting Swagger to reflect the use of custom serializers and deserializers.
Because the JSON must conform to an established format (which is not particularly well designed) and I wanted to have a properly designed API model in the Java classes, I have used a few custom implementations of JsonSerializer to generate the JSON output. When I enable Swagger with annotations in the Spring-MVC controllers, the generated documentation ignores the custom serializers and describes the model as if it had been serialized with the default Jackson settings. So far so good, I didn't really expect Swagger to automatically understand the implementation of the serializers.
What I however would expect (and I can't find anything about this in the Swagger documentation) is a way to use Swagger annotations on the relevant attributes in the model classes to manually describe the model. Am I missing something or is it really not possible to Swagger as a documentation tool in connection with custom serializers (or deserializers for that matter)?
Edit: The Swagger documentation is not particularly good, but I have already tried to work with #ApiModelProperty on the deviating properties. As far as I can see, it has absolutely no effect on the generated output (tested with Swagger-SpringMVC 0.8.5 and 0.9.5).
You can use model substitutes for e.g. Lets say you have a service
#RequestMapping(value = { "/some-resource" }, method = POST,
consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE)
#ResponseBody
public ResponseEntity<Void>
businessTypeEcho(#RequestBody CustomSerializableResource business) {
return new CustomSerializableResource();
}
you can setup a type substitution rule that tells springmvc how to represent the custom serializable type in the swagger ui.
#Bean //Don't forget the #Bean annotation
public SwaggerSpringMvcPlugin customImplementation(){
return new SwaggerSpringMvcPlugin(this.springSwaggerConfig)
.apiInfo(apiInfo())
.directModelSubstitute(CustomSerializableResource.class, SubstitutedSerializableResource.class)
.includePatterns(".*pet.*");
}
class SubstitutedSerializableResource {
//getters and setters that describe what
//CustomSerializableResource should look like in the UI
}
Unfortunately, this is going to create a parallel universe of types that aren't used at runtime.
Update:
If I understand your comment correctly, you're using it to format system-wide types i.e. booleans to Y/N or dates to mm/dd/yyyy perhaps. IMO, what you're probably looking for is to use model substitutes (see example above).
Substitute Date with String (this is the prescriptive guidance) In the case of dates your only option to communicate the format expected unfortunately is only via a textual description of the particular field or property.
Substitute Boolean with a enum you can create i.e. YesNoEnum that represents how you expect the objects to be serialized. This will provide the documentation with a set of allowed values.
At the end of the day, its a trade-off between creating these meta classes just for documentation vs. standardizing the API models to use serialization primitives as much as possible.
I have some POJOs that are used to shuffle data around in my application and its webservices. We have just introduced an annotation to help us verify that String fields in those POJOs are of a certain length. This lets us validate the POJOs instead of waiting for the database layer to puke out an exception when it persists.
I would now like to do an analysis on those objects that will tell me what fields are Strings that do not have this new annotation. I want to do this so that I can get a list of fields that do not have this annotation so that it can be compared to its corresponding DB field and have the annotation added with the right length as its parameter.
No we cannot get a better correlation between our POJOs and our database objects.
No our database objects don't have this validation available. We really want this validation to happen on the POJOs as it is simpler to validate and report on invalid data at runtime.
Is there some static analysis tool that would help me with this task?
Sure.
Parse the Java code. Walk the AST. Find the fields of interest (may require that you also do name and type resolution ("symbol tables") so you can tell your fields from arbitary other fields) in the ASTs for your classes, and inspect the AST for the desired annotation.
You can do this with any Java AST parser (and name resolver). I think Eclipse can provide this. Our DMS Software Reengineering Toolkit can do this. ANTLR appears to have a Java parser, but I doubt if it has Java name and type resolution.
I opted to use annotations for the runtime validation needs and then crafted a unit test to verify that all fields were annotated. This was inspired by #c0mrade .
So the annotation is #Length and requires an integer parameter. At runtime the validator iterates over fields and looks for the #Length annotation and makes sure its applied on a String field. It then looks at the length of the Strings value and makes sure it is less than or equal to the parameter for the annotation.
In a unit test I load all of the classes for my POJOs by package. I then iterate over those classes, iterate over each classes fields, and finally check and see if the field is a String and has the #Length annotation assigned. If the field is a String and does not have #Length, it adds the class and field name to a list of Strings. The assertion for the test is that this list is empty.