Spring Cloud Function-suitable for REST API? How to access GET path params? - spring

I'm new to WebFlux and Serverless. I'm trying to create a REST API as Serverless via AWS API gateway.
The flow would be API Gateway --> Lambda --> DynamoDB
In order to achieve the API flow, would the Spring Cloud Function be the best choice? I found aws-serverless-java-container does the job seamlessly(wrapper of converting the event to http request/response)
I've gone through the documentation on http://cloud.spring.io/spring-cloud-function/single/spring-cloud-function.html and few examples found in https://github.com/spring-cloud/spring-cloud-function.
But still, I'm not convinced on whether with Spring Cloud Function I would be able to achieve the API flavor.
#Bean
//How path or query params can be mapped?
public Function<Flux<String>, Flux<String>> getEmployeeDetails() {
// business logic goes here
}
In the above snippet, how to achieve the GET request/response model. If my endpoint has /{dept}/{employee}/{name}, how Spring cloud function accepts the path params in GET request?
Any pointers would be helpful.

API Gateway wraps all data of the incoming request into an APIGatewayProxyRequestEvent object, which has several attributes, like the request body, path and query parameters, or the HTTP method of the original request.
For your use case, you would get the three path parameters dept, employee, and name.
However, the problem is that SpringBootApiGatewayRequestHandler, which does the mapping between the incoming APIGatewayProxyRequestEvent and your function, currently only considers a request body, but no other parameters at all.
I hope that the developers will fix this in the future.
In the meantime, you could implement a modified version of SpringBootApiGatewayRequestHandler, which considers the required parameters.
I've written a small article, which covers exactly this topic.

I have the same mistake with this, the documentation prompts you to think that you can do this, but you can't. This is only an example from spring-cloud-function, and springboot function aws specific code doesn't have this feature implemented (as far I could see).
You can follow the default route, if you want to implement your application in lambda with spring: https://github.com/awslabs/aws-serverless-java-container/blob/master/samples/springboot/pet-store.
Or... If you want, you can try the hard way, but attemption: you are completely alone: https://github.com/arawn/building-serverless-application-with-spring-webflux.
This project himself implements ObjecMapper conversions and you can get the parameters from request: https://github.com/arawn/building-serverless-application-with-spring-webflux/blob/master/src/main/java/serverless/aws/springframework/http/server/reactive/SimpleAPIGatewayProxyServerHttpRequest.java
The trick from here is to create Path template in lambda with proxy (Path: '/{proxy+}') and request are delegated from aws mapper.
Good luck!

Related

calling a rest endpoint in a springboot application

which is better alternative for calling REST endpoint in springboot application, calling REST endpoints using WebClient or calling REST endpoints using RestTemplate ?
Spring’s documentation recommends using WebClient, but that’s only a valid recommendation for reactive apps. If you aren’t writing a reactive app, use OpenFeign instead. Like anything else in software, it fits well for some cases, but might complicate things for others. Choosing WebClient to implement the REST endpoint calls is strongly coupled to making your app reactive
RestTemplate gives many advantages if you are using it from within Springboot application, i.e. in your server side to another part of your own app - sort of like an internal call. Because the RestTemplate "knows" all your entities and beans and so if you need to send over or receive an object which is known within your springboot application RestTemplate can map them automatically which is a very nice advantage. If you sending a request to some third party api and do not pass or receive your known entities RestTemplate is still a valid option but it just becomes just another Http client. Its just simply there as part of Springboot provided tools. But in this case you may use any other client as well.

How do we design a spring integration system where from the first call response we will have to decide which gateway to follow

**Spring Integration:**Need to design a system where from the first call response it will be decided which gateway to go to in the spring integration.
Was trying to implement first gateway as the common call then another gateway to segregate the different gateway calls. As we need gateway for the first interaction.Looking for other better design than this.
I cannot post the code in here due to security reason but i think using gateway for the first interaction and then based on the response if we use the router for segregating the call would help over here. Thanks!!

Spring boot metrics for rest api with PathVariables

In my spring boot project I would like to keep count of how many times the rest api endpoint responded with status 200. The spring boot actuator metrics endpoint came close to solving this issue for me out of the box.
However, the /metrics endpoint names provided the aggregate of responses by the endpoint method rather than each of the dynamic endpoints created through #PathVariable.
For example:
while I can get http://localhost:8084/myproject/actuator/metrics/http.server.requests?tag=status:200,uri:/api/users/{id}/books
I would like to do something like
http://localhost:8084/myproject/actuator/metrics/http.server.requests?tag=status:200,uri:/api/users/1/books
and
http://localhost:8084/myproject/actuator/metrics/http.server.requests?tag=status:200,uri:/api/users/2/books
and so on.
Is there an easy way to do this?
You can roll your own WebMvcTagsProvider. That's the place where you can hook into the tag generation. Have a look at DefaultWebMvcTagsProvider to get insight on how it is done for the default behaviour.
A note: The default tagging is done on purpose the way it is to hinder metrics explosion, because every metric name + tag combination is a new metric. So be aware of that.

Zuul Proxy: Aggregated mapper on proxy routing

I have an application which looks like this
Now, whenever a request is received at the gateway, Zuul filter AuthorizationInterceptor gets invoked which does authentication/authorization by making some calls with User Service. If the authorization succeeds then actual microservice is called.
Now the with the new requirement, I need to write some aggregated API which takes data from two services and combine the data. So I added #RestController on Gateway Proxy but before that rest controller gets invoked AuthorizationInterceptor is not getting invoked. How can I tell ZuulFilter to get invoked even when the request is locally served.
Is there any solution for this? Should this be architected in a different way?
I don't think it's a good idea to put this kind of logic into the gateway service.
What you are referring to is an aggregator service which can be after the gateway as the other two services but instead of storing data or doing some business logic, it just takes the data from the two other services and aggregates them. This way the AuthorizationInterceptor will be invoked on the gateway level as well.
Another hacky approach would be to create a custom ZuulFilter which handles an imaginary endpoint call and aggregates the data. This way your AuthorizationInterceptor will be called as well but it's not a good idea to put this kind of logic into your edge service.

how to make spring mvc functions available for rest calls

I have a spring mvc application which runs correctly,now another colleague wants to call the same functions from another application but he needs REST URL of my functions.
how is it possible to provide the same functionality through spring REST?
is it just with new annotations .please provide some resource to show me how to do it.
when server has a service, only legal clients which had any contracts with server can access it. And clients can use service by the way such as: use RestTemplate to get/post request to URL of service, and clients can get data as JSON, or XML type if you have an equivalent object as this image:
Also, a service can be support as a interface, ex: google search is a service supported by google, but it's not rest service.
If you know each other URL address you can consume each other REST API from java code by using RestTemplate object.
I would advise you to go over the Spring starter guide which deals with that issue, here is the link (Consuming a RESTful Web Service):
https://spring.io/guides/gs/consuming-rest/

Resources