Renaming APIs in swagger with Spring - spring-boot

I understand that when documenting an API with Swagger in Spring, I can change the description for the API by adding #Api annotation, but when I add it as follows
#Api(value= "NEW_NAME", description="NEW_DESCRIPTION")
Only the description is changed, not the name.
as seen here
Further, I'm not sure where the default name and description are coming from, before adding the API, the name seems to be derived from the controller name, but the description; which to me looks natural and human like almost like hard coded String with capitalization and all.
I ran a search on the code, and I wasn't able to find those Strings. Where's Swagger getting those values from?
thanks

The attribute you are looking for is: tags. So you can avoid grouping by controller name.
From Javadoc of #Api tags:
Tags can be used for logical grouping of operations by resources or any other qualifier.
For example:
#Api(value = "/customers", tags = "customers", description = "Manage Customer")
By default Springfox creates API with name as {controller-name}-controller and description as {Controller Name} Controller (cf. How to change the default Controller Name in Swagger Spring ).

It seems that the current way to do this is:
#Api(description = "Manage cars", tags = { "Cars" })

Default -
{controller-name}-controller
For Custom Name Add -
#Tag(name="YOUR CUSTOM NAME HERE")
on the Controller Class
Example -
#RestController
#Tag(name="1. Project Resource")
public class ProjectResource {...}
Result -

Related

REST Spring boot validation causing code duplication

I have defined two Spring boot REST resources
POST /customer
The above resource is for adding a customer with the below JSON as a request
{
"customerFirstName" : "John"
"customerLastName" : "Doe"
"customerAddress" : {
"addressLine1" : "22 XYZ Drive"
"addressLine1" : "22 suite"
"state" : "PY"
"country" : "Ind"
"zipCode" : "1235312"
}
}
Now I need to implement update the customer info, so the below resource is defined. The requirement is any information related to customers can be updated. So the Input JSON in case of an update is the same as in the case of add request. The only caveat the information that is not provided will not be updated. Only information that is provided will be updated.
PUT /customer/{customerId}
Question : I want to use Spring boot Bean request validation. However, the validation requirements are different for adding and updating resources, so not able to use the same Customer domain model. However, the domain model in both cases is exactly the same so this is causing a code duplication. How can I avoid that or is it correct to move the validation outside and code.
Example : In the case of adding a customer it is mandatory to provide a customer address, so one can use annotation like #NotNull. However, in the case of updating the customer, the customer address is not mandatory.
You should be able to use validation groups and keep a single model class. Each constraint has groups attribute that you can use to define a validation scheme. You can have a Create group that you'll use only in the POST request and ignore in the PATCH one:
interface Create {}
class Customer {
#NotNull(groups = Create.class)
private String firstName;
#NotNull(groups = Create.class)
private String lastName;
//....
}
And then as you are using Spring you'd want to take a look at #Validated annotation. This one allows you to define the particular groups you want to validate against:
#PostMapping("/customer")
public ResponseEntity<Customer> create(#RequestBody #Validated(Create.class) Customer customer) {
// do your thing
}
You can also check this part of the documentation to learn more about groups and their capabilities

Spring boot model class property validation

I am trying to map a json object to a Spring boot model class now the contract says for a property it have only a certain set of allowed values(not more than 3).
Example:
Suppose that json has field "name" and the contract says allowed values for field "name" are john,todd,phil
Anything other than john,todd,phil wont be accepted.
Is there any way to achive this constraint using any annotations
You can use following solutions
Solution 1:
Using #Pattern annotation with regex , if you want to use case insensitive use appropriate flags
#Pattern(regexp = "john|todd|phil", flags = Pattern.Flag.CASE_INSENSITIVE)
Solution 2:
By creating a enum class type with allowed values
public enum {
JOHN, TODD, PHIL
}
In your model class use #Enumerated(EnumType.STRING) on name filed

Swagger override #JsonProperty("") annotation

In my code I am using #JsonProperty("") for naming fields in JSON response.
Like
#JsonProperty(value = "UserData")private List<UserEntity> userEntities;
And I am getting API response correctly ( that filed name is 'UserData')
but in swagger HTML file the filed name is getting as 'user_data'
In my application.properties following properties are set SNAKE_CASE as default.
spring.jackson.property-naming-strategy=SNAKE_CASE
Could you please tell me how to resolve this. I need the field name as in the #JsonProperty(value = "UserData")
Could you try this?
#ApiModelProperty(name = "UserData")
Have you tried #JsonProperty("UserData")? as per this post

How do I set the default_language for Text Search with Spring

In my model I set the #TextIndexed annotation to add a field to the fulltext index of MongoDB:
#TextIndexed
private String descriptionShort;
This works so far.
But how can set the default_language to "De" for the index?
I noticed that the language is automatically set by Spring when a language property is found on the model entity.
At least the behaviour pointed to this conclusion.
However, I did not find any docs on this?
My model has no language property at this point so I wonder how to achieve this?
According to the unit test's the class can be annotated to the default language through the #Document annotation. There is also a section in the reference documentation. Basically using the same code as in the unit test:
#Document(language = "german")
static class TextIndexedDocumentRoot {
#TextIndexed String textIndexedPropertyWithDefaultWeight;
#TextIndexed(weight = 5) String textIndexedPropertyWithWeight;
TextIndexedDocumentWihtLanguageOverride nestedDocument;
}
static class TextIndexedDocumentWihtLanguageOverride {
#Language String lang;
#TextIndexed String textIndexedPropertyInNestedDocument;
String nonTextIndexedProperty;
}
}
Just to note that the #Language annotation there serves as the language_override setting, but this would actually happen within the "sub-document" as shown with the default field name of "language" anyway, and it a common pattern for enabling multi language support with different language phrases stored in the document.
Also note the language can be "german" or "de" as the ISO code, or anything that is supported on the Text Search Languages as listed in the documentation. Other options are available in the Enterprise Edition only.

Spring Data Rest Mongo - how to create a DBRef using an id instead of a URI?

I have the following entity, that references another entity.
class Foo {
String id;
String name supplierName;
**#DBRef** TemplateSchema templateSchema;
...
}
I want to be able to use the following JSON (or similar) to create a new entity.
{
"supplierName": "Stormkind",
"templateSchema": "572878138b749120341e6cbf"
}
...but it looks like Spring forces you to use a URI like this:
{
"supplierName": "Stormkind",
"templateSchema": "/template-schema/572878138b749120341e6cbf"
}
Is there a way to create the DBRef by posting an ID instead of a URI?
Thanks!
In REST, the only form of ID's that exist are URIs (hence the name Unique Resource Identifier). Something like 572878138b749120341e6cbf does not identify a resource, /template-schema/572878138b749120341e6cbf does.
On the HTTP level, entities do not exist, only resources identified by URIs. That's why Spring Data REST expects you to use URIs as identifiers.

Resources