spring boot rest versioned request and select controller dynamically - spring

We are planning to apply versioning to our REST API. We do not want to change the URL so the idea that we are going with is to have a X-API-VERSION in the HTTP header. When this header value is present the request is forwarded to correct versioned rest controller.
e.g. we have two controller for the same resource i.e. Person resource
PersonController
Person_Version_1_5_Controller
If X-API-VERSION is NOT present in the HTTP Header then spring by default will call the PersonController.
If X-API-VERSION is PRESENT in the HTTP Header then it should call Person_Version_1_5_Controller.
So how can we achieve this switching between controllers using spring boot?

Looking at Spring's documentation, it looks like the header parameter of RequestMapping might be useful in such cases:
#RequestMapping(value = "/something", headers = "X-API-VERSION=...")

I think you're approaching this from the wrong angle.
Instead of keeping controllers for different versions in the same application deployment (Person_Version_1_5_Controller is not a pretty name, by the way), you could split them in separate JARs / application deployments, e.g. app-v1.jar and app-v2.jar. You could do the routing on a higher level in your stack, using a HTTP-header based load-balancer that would forward the request to the correct version of the app depending on the version header specified in the request.

Related

How do I add an optional global request header to openapi/swagger 3 documentation in Spring Boot?

I have a spring boot project that uses openapi/swagger 3 annotations for documentation. Since the project is behind a Zuul gateway, there is some pre-processing of requests before they reach specific REST endpoints. Some of that pre-processing is controlled by an optional custom header - eg, X-Custom-Header. I want to add the ability to send that header on all requests into the system, but since it's not used in any of the actual endpoint logic, I don't want to have to add the header field to every endpoint method. I was hoping it would be possible to modify the OpenAPI object, similarly to how we add a security scheme, but I can't find anything that creates the requisite functionality. Am I missing anything?

Is it possible to disable Spring Cloud Sleuth header propagation based on destination URL?

We're using Brave's ExtraFieldPropagation feature to propagate custom fields (e.g. an internal-only request identifier) between services as HTTP headers.
Some of our services make requests to external services using a RestTemplate or Feign client in the course of processing a request. Since Sleuth enhances all RestTemplate beans and Feign clients with the propagation feature, this means that external services receive the internal-only headers, which I'd like to avoid.
I know of two workarounds that allow me to avoid this behavior, both of which are flawed:
Instantiate a client object manually as opposed to using a #Bean so that Sleuth does not add an interceptor. The downside I see here is that developers have to remember to follow this pattern to avoid leaking information, and this is difficult to enforce.
Add an interceptor that removes these headers from outgoing requests. The downsides here are that a) I need separate interceptors for RestTemplate and Feign clients (not a huge deal); b) it looks like Feign client interceptors do not have a way to influence order of execution (see javadoc here), so I can't guarantee that the new interceptor will run last / after the Sleuth one.
Is there a way to customize Sleuth (e.g. via some kind of injector bean) such that, prior to injecting headers in an outgoing HTTP request, I can reason about the destination of the request? I saw documentation regarding custom injector beans, but it appears those no longer exist in spring boot >= 2. I can't seem to find an equivalent construct in Brave.
You can unsample a given URL which means that the headers will be propagated but not sent to Zipkin. You can't disable instrumentation for only some of the URLs cause we're instrumenting all of the components that are registered as beans.

Is it possible to create a proxy controller that ignores some part of the URI

I have a spring service with multiple controllers with following request mapping running on port 9000
/api/fruits
/api/vegetables
/api/plants
Given all these requests are being served at localhost:9000,is it possible via some Spring entity, that a request to localhost:9000/{Account_id}/api/fruits is routed to localhost:9000/api/fruits. I know the question is a little vague but I'm trying to see if I can add a proxy controller with mapping /{account_id}/ which ignores the rest of the uri and have some code there to forward it to the appropriate controller. Not sure if Spring interceptor or filter of some sort would be helpful here for me to modify the request and change the URI

Setup Spring Filter using annotation

I am really new to spring and wanted to make a simple web application that uses JWT based authentication.
I have an endpoint on my server (/token) that returns JWT tokens to my client.
These clients then make requests to my server using that token. I was wondering how I could implement something like this:
#Secured("Admin")
#RequestMapping("/users", method=RequestMethod.DELETE)
public #ResponseBody String deleteUsers(){
...
}
From what I could gather, I would need a filter that would validate my JWT token that is sent along with every request the client makes. Is there any way in which only requests that have a #Secured annotation are passed through that filter?
Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration depending on which services are required. The ordering of the filters is important as there are dependencies between them. If you have been using namespace configuration, then the filters are automatically configured for you and you don't have to define any Spring beans explicitly but here may be times when you want full control over the security filter chain, either because you are using features which aren't supported in the namespace, or you are using your own customized versions of classes.
link

Forward Spring HTTP Request

I have a restful web service written using Spring WebMVC that will mostly be used to orchestrate other services. In some cases these services are on the same server, in some cases they are not. I have a few requests (GET and POST) that will be direct pass throughs to another service. Is there a way to blindly forward all GET and POST data from a request for certain URLs without knowing anything about the data in the request?
Ideally, I would like to be able to say all requests for http://server1/myService/user/... should forward to http://server2/user/... with all of the GET and POST parameters forwarded with it.
For the services on the same server, if they're being served by the same Spring MVC application, you could use RedirectViews and/or the "redirect:" prefix.
For those on another server, the best thing I can think of would be to use a servlet filter, similar to the approach suggested by this post: spring mvc redirect path and all children to another domain

Resources