I have to write an API call
#GET
#Path("/{settingName1, settingName2}")
public Response getNetworkSettingValue(#ApiParam(value = "Name") #QueryParam("name") String name,
#ApiParam(value = "City") #QueryParam("city") String city,
#ApiParam(value = "State") #QueryParam("state") String state) {}
here my doubt is how to get settingName1 & settingName2 values,
can write like
#ApiParam(value = "SettingName1") #PathParam("settingName1") String settingName1
or
#ApiParam(value = "SettingName1") #PathVariable("settingName1") String settingName1
in method declaration.
or
any other way to get those two values
By the #Path annotation, I assume you are using JAX-RS (Jersey, RESTEasy, etc). So it should be:
#ApiParam(value = "SettingName1") #PathParam("settingName1") String settingName1
If you were using Spring, it should be:
#ApiParam(value = "SettingName1") #PathVariable("settingName1") String settingName1
your annotations are mixed up with spring and swagger.
If u want to accesss pathvariables with spring than it have to be like
#RequestMapping(value = "/{settingName1}/{settingName2}", method = equestMethod.GET)
public Response getNetworkSettingValue(#ApiParam(value = "settingName1") #PathVariable final String settingName1,
#ApiParam(value = "settingName2") #PathVariable final String settingName2) {
...
return new Response();
}
Related
I have a requirement in which I need to map the request body to a particular child class based on the path variable. The request body does not contain by itself any information as to which child class to pick.
#ApiOperation(value = "Update Developer (dev)",
response = ResponseEntity.class)
#RequestMapping(method = RequestMethod.PATCH,
value = "/{type}")
public ResponseEntity<Response> updateDeveloper(
#PathVariable String type,
#RequestParam("year") String year,
#RequestBody Developer employeeUpdate,
) { .....}
#ApiOperation(value = "Update Manager (manager)",
response = ResponseEntity.class)
#RequestMapping(method = RequestMethod.PATCH,
value = "/{type}")
public ResponseEntity<Response> updateManager(
#PathVariable String type,
#RequestParam("year") String year,
#RequestBody Manager employeeUpdate,
) { .....}
Where Developer and Manager extends abstract class Employee.
I tried by having only one method like below:
#ApiOperation(value = "Update Employee (manager, dev)",
response = ResponseEntity.class)
#RequestMapping(method = RequestMethod.PATCH,
value = "/{type}")
public ResponseEntity<Response> updateEmployee(
#PathVariable String type,
#RequestParam("year") String year,
#RequestBody Employee employeeUpdate,
) { .....}
But spring is unable to instantiate the Employee instance as its abstract.
Is my design incorrect? I do prefer to have a solution which doesn't require to modify the Employee/Developer/Manager classes.
Thanks in advance!!
By REST compliance, you should identify your resource:
#RequestMapping(method = RequestMethod.PATCH, value = "/developer")
#RequestMapping(method = RequestMethod.PATCH, value = "/manager")
If you still want to post a body randomly (which either a developer or a manager), you a combined DTO of Manager and Developer:
public class EmployeeDTO {
private int type; // Developer or manager
// All of properties of Manager and Developer
}
By inspecting type you are able to delegate to correct service method.
Thank you all for looking into this. I have found a way that suits my situation:
#ApiOperation(value = "Update Developer (dev)",
response = ResponseEntity.class)
#RequestMapping(method = RequestMethod.PATCH,
value = "/{type:developer}")
public ResponseEntity<Response> updateDeveloper(
#PathVariable String type,
#RequestParam("year") String year,
#RequestBody Developer employeeUpdate,
) { .....}
#ApiOperation(value = "Update Manager (manager)",
response = ResponseEntity.class)
#RequestMapping(method = RequestMethod.PATCH,
value = "/{type:manager}")
public ResponseEntity<Response> updateManager(
#PathVariable String type,
#RequestParam("year") String year,
#RequestBody Manager employeeUpdate,
) { .....}
With this I will not get any instantiation error as well, when trying to have single method and data type of request body is set as the parent.
For example, URL can be:
/api/groups?sdk&type=1
or
/api/groups?app&type=1
In java, I want to know the param in the url is sdk or app.
I have tried something like:
#RequestMapping(method = RequestMethod.GET)
public ResponseResult testGet(HttpServletRequest request, #RequestParam String sdk, #RequestParam int type) {
...
}
Basically you can have 2 methods and use the params variable in the #RequestMapping anotation to discriminate between the methods.
#RequestMapping(method = RequestMethod.GET, params="sdk")
public ResponseResult getSdk(HttpServletRequest request, #RequestParam int type) {
...
}
#RequestMapping(method = RequestMethod.GET, params="app")
public ResponseResult getApp(HttpServletRequest request, #RequestParam int type) {
...
}
You may or may not need to add the value = "/groups" to your request mapping, depending on how you have configured your class/app.
you can use a parameter for app and sdk so your url will be /api/groups?param=sdk&type=1 or /api/groups?param=app&type=1. you can find sample code below:
#RequestMapping(value = "/groups", method = RequestMethod.GET)
public RestResponse testGet(#RequestParam(value = "param", required = false) String param, #RequestParam(value = "type", required = false) String type) {
}
I am using Springfox and Swagger to generate swagger files. Right now I'm using #ModelAttribute to pull the variables from an object (NetworkCmd) to show as query params in the swagger doc.
I currently have the following controller:
#RequestMapping(value = "/{product_id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseHeader()
public ResponseEntity<?> networkResponse(
#RequestHeader HttpHeaders headers,
#PathVariable("product_id")String productId,
#Valid #ModelAttribute NetworkCmd cmd,
BindingResult result)
throws Exception {
...
}
And here is a sample of NetworkCmd:
#ItemId
#NotNull(message = "product cannot be null")
#ApiModelProperty(
value = "testing")
private String product_id;
#ApiModelProperty(
value = "key",
private String key;
#ApiModelProperty(
value = "parent")
private Boolean is_parent_id;
#Min(0)
#ApiModelProperty(
value = "radius")
private double radius = 10d;
One of the variables in this class is a custom domain object Nearby.
private Nearby nearby = null;
public Nearby getNearby() {
return nearby;
}
public void setNearby(String nearby) throws ParseException {
this.nearby = Nearby.parse(nearby);
}
This is kind of a special variable because it takes in a String, and then parses that string and turns it into the Nearby object.
My problem is that this Nearby variable isn't showing up on the generated swagger document through #ModelAttribute. I'm happy to provide any more information.
One way to get around this problem is to create an alternate type rule in your docket. This way anytime we encounter the nearby type we treat it as a string.
new Docket(...)
.directModelSubstitute(Nearby.class, String.class)
Is this the right way to have multiple parameters for a REST API ?
#GET
#Path("/id/{userId,type,date}")
#Nullable
#Produces(MediaType.APPLICATION_JSON)
List<Exercise> findExercises(
#ApiParam( value = "User ID", required=true) #PathParam("userId") Long userId,
#ApiParam( value = "Type") #PathParam("type") String type,
#ApiParam( value = "Date") #PathParam("date") String date);
If not, how can i accomplish that?
I guess this is the right way :
#GET
#Path("/id/{userId}/{type}/{date}")
#Nullable
#Produces(MediaType.APPLICATION_JSON)
List<Exercise> findExercises(
#PathParam("userId") Long userId,
#PathParam("type") String type,
#PathParam("date") String date);
You should separate the path params as follows:
#Path("/id/{userId}/{type}/{date}")
Lets say I have a Category domain model object that follows a file tree structure. I want to be able to construct a RequestMapping annotation for the controller method so that
/category/art/macros
/category/people/weddings/2014/5-19
/category/sports/college/baseball/2014/5-19
can be handled by the minimum number of controller methods.
I already have one controller method defined:
#RequestMapping(value ={"/category/{category}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category){
model.addAttribute("message", category);
return "gallery";
}
This works for a single URL like
/category/sports
How can I adapt this to be more flexible?
The challenge is here that you can't make #PathVariable optional but you can have two or more controller methods which can call the same service code. So, for you three URL patterns you have to define three different controllers:
GET: /category/art/macros
#RequestMapping(value ={"/category/{category}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category){
model.addAttribute("message", category);
return "gallery";
}
GET: /category/people/weddings/2014/5-19
#RequestMapping(value ={"/category/{category}/{subcategory}/{year}/{date}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category,
#PathVariable(value = "subcategory") String subcategory,
#PathVariable(value = "year") String year,
#PathVariable(value = "date") String date
){
model.addAttribute("message", category, subcategory, year, date);
return "gallery";
}
GET: /category/sports/college/baseball/2014/5-19
#RequestMapping(value ={"/category/{category}/{subcategory}/{year}/{date}"}, method = RequestMethod.GET)
public String adminCategory(ModelMap model, #PathVariable(value = "category") String category,
#PathVariable(value = "subcategory") String subcategory,
#PathVariable(value = "sub_sub_category") String sub_sub_category,
#PathVariable(value = "year") String year,
#PathVariable(value = "date") String date
){
model.addAttribute("message", category, subcategory, sub_sub_category, year, date);
return "gallery";
}
PS You can user #RequestParam which can be optional and reduce the number of controllers.