Description
Key information
- RFC PR: (leave this empty)
- Related issue(s), if known:
- Area: (i.e. Tracer, Metrics, Logger, etc.)
- Meet tenets: (Yes/no)
Summary
To fill the gap with Python and the REST API Handler module, we want to introduce a new module, to ease the integration with API Gateway requests (routing, cors, extracting parameters, ...).
Motivation
The integration between API GW and Lambda is probably the most common pattern used by AWS customers. Today, you can do it manually, which implies a lot of boilerplate code: routing, retrieving the headers & parameters & body of the request, deserialize the body, creating a response object (adding the cors headers), ... Or you can use frameworks that partially solve some of these features (ex: Spring routing). But there is not a single all-in-one easy-to-use framework, just like the Python version of this module.
If java was left aside for this kind of integration (because of cold starts), it should not anymore be the case with Snapstart. Having this easy integration would help our users focusing on the business side of their function and not the boilerplate code to make it work.
Proposal
The module should implement the JAX-RS API (at least partially), which is the Java standard to define REST APIs. See the javax.ws.rs doc and javax.ws.rs.core doc.
Here is an example of what it could look like for developers:
@Path("/todos")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class APIHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
APIGatewayRestResolver resolver = new APIGatewayRestResolver(this);
@GET
private List<Todo> getTodos(@QueryParam("sort") String sort) {
return Collections.singletonList(new Todo());
}
@Path("/{id}")
@GET
private Todo getTodo(@PathParam("id") String id) {
return new Todo();
}
@POST
private Todo createTodo(@HeaderParam("X-header-for-creation") String header, Todo todo) {
return todo;
}
@Path("/{id}")
@PUT
private Todo updateTodo(@PathParam("id") String id, Todo todo) {
return todo;
}
@Path("/{id}")
@DELETE
private void deleteTodo(@PathParam("id") String id) {
}
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
return resolver.resolve(event, context);
}
}
-
The module should handle the following annotations:
@GET
,@POST
,@PUT
,@DELETE
,@PATCH
http verbs@Path
on the classes and on methods- Must have:
@PathParam
,@QueryParam
,@HeaderParam
,@FormParam
, Nice to have :@MatrixParam, @CookieParam
. Parameters will be automatically extracted fromAPIGatewayProxyRequestEvent
- Must handle a non-param param (body). It should be deserialised automatically from the body of the request.
- Nice to have:
@Consumes
&@Produces
to specify the headers in the response
-
The module should be able to handle
javax.ws.rs.core.Response
object (and inner objects likeNewCookie
and others) and transform it into acom.amazonaws.services.lambda.runtime.eventsAPIGatewayProxyResponseEvent
. -
The module should be able to transform the exceptions (ex: BadRequestException, or InternalServerErrorException) into proper responses.
-
The module should be able to ease the CORS header: see RFC: Simplifying CORS #1029 and feat: module to ease cors configuration #831.
Drawbacks
- A lot of frameworks try to provide the same, do we need another one? I don't know if one has the developer experience I'm proposing above (or even better).
- Tightly coupled to JAX-RS (opinionated way to implement REST APIs, but at least a standard one).
Do we need additional dependencies? Impact performance/package size?
New module, with JAX-RS dependency (quite lightweight as it's just an API: 126 898 bytes)
Rationale and alternatives
-
What other designs have been considered? Why not them?
We could avoid the coupling with JAX-RS and have our own API (for example similar to what Python is providing). I believe the learning curve and the adoption will be easier by adopting such a standard. It makes the function easily readable and understandable. -
What is the impact of not doing this?
We can choose not to do this module and let people use their preferred framework but, unless I mistaken, there is not a single library that handles eveything with the same devx, and it should be much beneficial to have this layer on top of events/response and ease the routing, serialization, ...
Alternative frameworks/libraries:
- https://github.com/bbilger/jrestless
- https://github.com/cagataygurturk/lambadaframework
Unresolved questions
- Do we have to implement the full JAX-RS API?
Metadata
Metadata
Assignees
Labels
Type
Projects
Status