Multiple request model based on path param in Swagger | Spring - spring

I have a rest controller, where I am accepting the request body into a string. And then based on type in path param, transforming stringify request body into the corresponding model.
Example endpoint: /xyz/123/{type}
Let's say, the type could be A, B, C, and their corresponding models would be AModel.class, BModel.class, CModel.class.
The question is how can I expose this endpoint in the nicer way in swagger documentation. Looking for some easy and extensible way. I am using spring-fox, would be great if I don't have to write the swagger file explicitly.
I am using spring boot project. Explored a lot of link, but couldn't find thing I am looking for.
Thanks.

Related

Can we Document Model/entity with using Spring rest docs

Writing all fields with the snippets description is not reliable solution
is there any way to implement Model/Entity as a table with the fields and description, constraints, Type seprately.
fieldWithPath("id").description("Id of Student."),
fieldWithPath("name").description("Name of the Student."),
fieldWithPath("contact").description("Contact of the Student."),
fieldWithPath("marks").description("Marks of the Student."));
Documenting an entity directly is exactly what Spring REST Docs is designed to avoid. If that's the approach that you want to take then Spring REST Docs isn't the right tool for the job.
Spring REST Docs is built around the belief that, when documenting a REST API, it's the HTTP requests and responses that should be used to generate that documentation. This ensures that the documentation accurately describes the requests that the service expects to receive and the responses that it will send.
If you try to use an entity to document your API, you are ignoring the transformations that could be applied to that entity when serialising it to JSON. This can result in documentation that's inaccurate as serialization may omit some of an entity's properties, change the name of some of those properties, or even change the structure entirely.

How to list twice the same GET method in Swagger integrated in Spring Boot

I have a #RestController with a GET method to list all the instances of a Resource R
I want swagger-ui to list thrice this GET method like this:
findRByFoo
findRByBar
findRByFooAndBar
that corresponds to the following GET petitions:
/resources?foo=myFoo
/resources?bar=myBar
/resources?foo=myFoo&bar=myBar
so that the clients of my API Rest don't have to guess that they can search by foo or bar and can simply look at the swagger-ui (version 2.9.2) and use those API calls
However, given that the three methods are at the /resources path, swagger simply lists one of them and only one.
The question is, How may I list the three API calls?
Edit: It seems to be a limitation of Swagger 2 Unable to add multiple operations on same path in swagger rest API documentation #1378, so let me rephrase the question as:
How may I circumvent this limitation?
Does it mean that the design of my API Rest is not as Rest as should be?
I rewrited the RController to have a single GET
#RestController("/path-to-r")
public class RController
{
#GetMapping
public List<R> findR(Optional<String> foo, Optional<String> bar)
{
....
}
}
And added genericModelSubstitutes as explained in Java 8 Optional #RequestParam lost from the swagger-ui #1848
The final result is such that when the clients of my API click in the combo they can see the two optional parameters to include in the GET petition

Can i access request parameter in jackson BeanSerializerModifier?

I am using Jersey to implement rest api and Jackson to provide JSON support. I am trying to remove certain properties before serialization by overriding BeanSerializerModifier.changeProperties method.
But removing properties will be based on query parameter. Is there any way to access the query parameter in my implementation?
Use of BeanSerializerModifier itself would get complicated as the method is only called once when construction necessarily JsonSerializer for the first time. As to passing query parameters, you could pass them using contextual attributes and ObjectWriter (constructed from ObjectMapper), but that means taking over quite a bit of serialization automation from Jersey.
There is one mechanism that could be helpful in modifying serialization aspects without taking over the whole process: registering ObjectWriterModifier, using ObjectWriterInjector. These are part of Jackson JAX-RS provider, added in Jackson 2.3. Without knowing more details I don't know how easy this would be; part of the issue is that query parameters are more of an input side things, so there is no direct access to them from output processing side.

How to return representations of associations in a Spring Data REST resource?

There are following URLS - /users/2/profile , /users/2/userPosts
I need to concat output of both Spring Data REST results in server side and build single JSON from them and send on different URL /users/2/custom.
So, I am thinking to make 2 calls to SDR urls from Spring MVC, can we do this using RestTemplate and some JSON concat utility , here server and database is on same machine so RestTemplate will probably have localhost
An example will help
You might rather want to look into the projections feature of Spring Data REST which allows you to craft custom responses by using interfaces as described in this blog post.
As both properties (profile and userPosts) seem to be associations of a user item resource it should be sufficient to do something like this:
#Projection(types = User.class)
interface UserWithDetails {
// List getters for basic properties you want to expose…
// Add dedicated getters for associations to be included
Profile getProfile();
List<Post> getUserPosts();
}
Clients can now pass a projection parameter to the resources exposed to see the expanded representation.
As an alternative, you can create these kinds of interfaces for Profile and Post and configure #RepositoryRestResource on the repositories for both of these types to contain excerptProjection = YourProjectionInterface.class. This will cause the projections to be rendered whenever an association is included in the response (i.e. an actually-linked-to-resource could be embedded).

Jersey - data validation before sending entity object to REST api

I use Jersey framework to communicate (marshalling and unmarshalling object and xml) with REST api. I send data (object has lot attributes) this way:
.
.
ClientResponse response = webResource.type("application/xml").post(ClientResponse.class, object);
.
I would like to ask how can I validate some object attributes (for example private String code in Object should be in format of two numbers etc.)
aYou mean in the service that receives the object? How have you tried? It comes in as an object, or whatever you want it to come in as. We frequently take in Map<String,Object> and then do validation on that map (if we need to decide what subtype to create from the post for example). If you have Jersey unmarshall your request into the POJO for you, you can then do whatever validation you want and return a Response object with the validation error information to your client if the object doesn't pass.
So in other words, the validation is up to you. There are a few validation frameworks out there that you could try to help, such as javax.validation but IMHO it's usually easier to just test each property you need to validate yourself using conditionals, regexps, whatever.
In my opinion the validation comes with a webframework like struts, wicked, jfc... to name some. There the user inputs his data in a form to create the object he wants to post to a service. The webframeworks already got components to validate this data. When there was a positive validation you make the post call to your service.

Resources