Let's assume I want to follow the API-first approach with openapi. The response of an endpoint should be a JSON of Java objects whose classes are implemented in a third-party library. Thus, they already exist and are not under my control.
What is the best option here to specify the API?
Define a new DTO type in my openapi spec and implement a mapper from existing class to generated DTO class? Feels like boilerplate code.
define the response to be a string and mention in the description that the String encodes a JSON of an existing-class object. This would cleary generate ugly code.
There isn't a way to reference existing Java classes in the spec file, I guess.
Related
I am using JAX-RS whereby I have an interface which contains annotated methods for my endpoints (Apache CXF). I am using Jackson as my serializer.
I have noticed that the first request is particularly slow. This is because the JSON serializer is building its internal metadata on how to serialize/deserialize a given type on the first request.
It is possible to get Jackson to do this upfront (before the first request) by registering the type with Jackson. Is it possible to do this in a generic way, such that I have an interface and using reflection it goes and finds all the inputs and outputs to the JAX-RS annotated methods and registers the types with Jackson?
I figured this must be an "already solved" problem and in the vein of DRY - is there something out there that will do this already without me having to write some nasty reflection code myself? (Or any helper methods in Spring etc that could help here?)
I'm looking for a solution which automatically generates POJO classfiles from a given .yaml-Files but have not found anything like this yet.
I can not imagine that it should be the only way to write these classes yourself.
The problem is that YAML describes objects, not classes. In general, you cannot automatically derive a POJO structure from a given YAML file. Take, for example, this YAML:
one: foo
two: bar
In YAML, this is a mapping with scalar keys and values. However, there are multiple possibilities to map it to Java. Here are two:
HashMap<String, String>
class Root {
String one;
String bar;
}
To know which one is the right mapping, you would need a schema definition like those for XML. Sadly, YAML currently does not provide a standard way of defining a schema. Therefore, you define the schema by writing the class hierarchy your YAML should be deserialised into.
So, in contrary to what you may think, writing the POJOs is not a superfluous action that could be automated, but instead is a vital step for including YAML in your application.
Note: In the case that you actually want to use YAML to define some data layout and then generate Java source code from it, that is of course possible. However, you'd need to be much more precise in your description to get help on that.
As pointed out in the comments by Jack Flamp, you can use an online tool (jsonschema2pojo) to convert a sample yaml file to its equivalent POJO classes. This tool can convert json or yaml data to corresponding POJO classes and I have used it successfully in the past.
That being said, the tool is forced to make certain "assumptions" when you are using a yaml file(instead of yaml schema). So, it would be a good idea to look at the generated classes carefully before you start using them.
You can find more information about how to use this online tool from its wiki page.
The Accepted Answer is incomplete.
You can try to use https://editor.swagger.io/
After importing yaml file You can generate Java REST Client project through menu with correspondent POJO classes.
I'm using springfox for auto-generate swagger-api-document from my spring-mvc restful application.
To make the api clear, i'm using #ApiModelProperty to add describe for response field. Recently there's an api which response a third-party model which i can't add #ApiModelProperty to it's source.
So how to add #ApiModelProperty for third-party model which it's not controlled by you?
You have several options.
First, the response model does not need to be the concrete class that you're returning. So it might be UserDTO but you can easily declare it as User. That gives you the chance to create an interface or even extend your concrete class and add the #ApiModelProperty annotations.
Next, most frameworks allow you to intercept the Swagger document before it's rendered. You can probably manually mutate the doc, and add the descriptions and metadata that you need.
I'd suggest going with the first approach as it's easier to implement and gives you all the control you need.
I'm not talking about using the REST classes, like #Path or #POST.
I'm talking about how to translate any REST definition into a model of classes - A model from which many things can be done, like generating client code or parsing incoming data.
A bonus might be to parse an existing Resource class and create the model for it's REST API.
Example of such class might be Resource. A resource must have a path. A resource would have methods, like GET or POST. Methods would have params. And so on...
Methods can be different by definition, for example A POST method can have a stream of data, whereas GET cannot.
So, how to model a REST implementation using classes?
You might find this post interesting : http://dalelane.co.uk/blog/?p=1871
It generates HTML file with an entry for each of a REST end-point in a specific path.
I am in the process of building a REST api which accepts a set of arguments, processes it and gives a boolean response.
My question is how do I build a dto object. I can create a Java POJO in one of the applications and use it as REST parameter but that creates a dependency on this application.
Is there a better way to pass an object as REST parameter?
note: the reason I am not using path params because my dto object might contain a list of objects as well and I am not sure how to pass that using path param.
You can create a library which contains the DTO class if dependency is your concern.
After all the DTO is dependent on the REST API. If one changes the other must change too.