Possible to use #RepositoryRestResource with #PathVariable instead of #Param? - spring

I have a RestRepositoryResource which is working properly. However, I would prefer to structure URLs using path variables instead of query parameters. The goal would be this:
http://localhost/persons/findByLastName/Smith/
instead of this:
http://localhost/persons/findByLastName?lastName=Smith
I have played around with various annotations but not achieved this using RestRepositoryResource. Is this possible or does this have to be done with a Controller resource mapping?

Spring data repositories don't support the #PathVariable annotation right now. However a simple workaround for this problem might be to use URLRewriteFilter internally re-route the request for http://localhost/persons/findByLastName/Smith/ to http://localhost/persons/findByLastName?lastName=Smith without the user noticing.

Related

in spring boot, what's better? using multiple repositories in one service or using multiple services in one controller?

I am trying to make this rest endpoint : /api/Offers/{offerId}/comments, what is better in design view?
using CommentRepository and OfferRepository inside OfferService
OR
using CommentService and OfferService inside OfferController
It is sort of specific to general issue, I don't know what is most recommended approach!
I would pick the second variant:
using CommentService and OfferService inside OfferController
There is no special reason for that, but for me its clearer, other than the repositories. (Only my Opinion)

spring boot: separate REST from static content

I'm using spring-boot-starter-data-rest and spring-boot-starter-web.
I've made a simple project using a CrudRepository, letting spring boot generate the rest request mappings.
Now, I want to add a client -- making the rest calls -- live under ./.
Hence, I'm trying to prefix the paths for the rest calls (and only those!) with /api.
I've tried the answers from :
How to specify prefix for all controllers in Spring Boot?
using settings in the application.properties file
server.contextPath=/api/*
spring.data.rest.basePath=/api/*.
But still the static content (e.g. index.html, *.js, *.css) is not fetched using ./. There urls are also prefixed by "/api/".
The rest calls are properly served under /api/foos.
Is there a way to tell spring not to treat urls that lead to sources located in src/main/resources/public as 'rest-controllers'?
Update
Setting the property
spring.data.rest.basePath=/api/*
works perfectly. (I still had a programmatic bean configuration in my sandbox overriding this setting).
Spring controllers are made for serving both HTML and JSON/XML. The first one is done via Spring MVC Views and some template engine like Thymeleaf, the latter is handled entirely by Spring and #RestController.
There's no way to have a context path for only the controllers that returns JSON or XML data, and not for the other controllers as well, this also goes for static content. What you typically do is have some static variable containing the prefix you want for your APIs, and the use that in the controller's #RequestMapping. i.e.
#RestController
#RequestMapping(MyConstants.API_LATEST + "/bookings")
public class MyBookingsController {
...
}
You probably want to approach the prefix problem with something along these lines anyway. It is common to have to support older API versions when you have breaking changes, at least for some time.

Spring RequestMapping annotation implementation

can someone please tell me where I can find the source code that processes #RequestMapping annotation. I want to make a similiar annotation.
I know it's somewhere on https://github.com/spring-projects/spring-framework/
But i haven't found so far where the actual processing takes place.
You can simply plug #RequestMapping text to the search field on the top of GitHub project page to see where that class is used.
Here is the direct link. https://github.com/spring-projects/spring-framework/blob/1204d2aef4afdefb4ba73c86565aab3f5b2a6931/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/DefaultAnnotationHandlerMapping.java

Enunciate validation of Jersey API fails with #POST #FormParam + String data

I'm evaluating enunciate to document our REST APIs and I'm having an issue with the validation step:
Validation result has errors.
my.java: error: [core] An entity parameter must be of type MultivaluedMap<String, String> if there is another parameter annotated with #FormParam.
#FormParam("my-param") String myParam, String data)
This construct of accepting the POST data as a String entity in addition to #FormParam bindings is supported by Jersey, so not sure why enunciate is choking on it? Is this not JAX-RS compliant?
This is a really useful to capture the full post data for auditing purposes if something went wrong. Is there a way to configure enunciate to ignore this argument?
If not, is there some other way to capture the post data in a way that would keep enunciate happy? I'm reluctant to go to MultivaluedMap as the stringification process may not result in exactly the String which was passed in...
Thanks!
It may be that the validation checks Enunciate performs are outdated. You might consider requesting a change by submitting a JIRA issue.
One thing you could try as a workaround is to create your own custom parameter annotation and configure Enunciate consider it as a custom resource parameter.
<enunciate>
...
<services>
<rest>
<custom-resource-parameter-annotation qualifiedName="org.myco.CustomResourceParam"/>
</rest>
</services>
...
</enunciate>
However, if the purpose of the parameter is for auditing, I'd really recommend using a Jersey filter. That way you don't litter your API code with auditing concerns.

Spring overwriting controller

I provide a highly customisable application to my clients which is working totally by itself. But If one my client wants to overwrite any Controller, I want to replace my implementation by theirs. However just overwriting the controller causes an ambiguous definition of mappings.
I have been using Component Scanning to load beans.
The potential solutions came to my mind are:
Using component scanner with excluding by a custom filter? (This seems not so easy)
Using a xxxxPostProcessor to remove some beans? (How?)
Any help?
If I got your Question properly,
You can differ implementation by changing URL to particular Implementation name
Say Telecom is interface and AirtelImpl and RelianceImpl are Controllers then
Your request mapping
#RequestMapping(value= "/airtel/doBilling")
#RequestMapping(value= "/reliance/doBilling")
In this way, Implementation flow will differ.
I have followed these steps:
Created a custom annotation: #Devoted
Created a custom ImportBeanDefinitionRegistrar. Iterated already registered bean definitions to find out `#Devoted #Controller's and removed them.
Based on a request I will provide implementation details.

Resources