Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add Rest API Event Handler module #1103

Open
jeromevdl opened this issue Mar 20, 2023 · 7 comments
Open

RFC: Add Rest API Event Handler module #1103

jeromevdl opened this issue Mar 20, 2023 · 7 comments
Labels
blocked Tasks that can't be started yet enhancement New feature or request feature-parity Feature parity with python version priority:5 Unknown - Idea for later RFC size/XXL

Comments

@jeromevdl
Copy link
Contributor

jeromevdl commented Mar 20, 2023

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);
    }
}

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:

Unresolved questions

  • Do we have to implement the full JAX-RS API?
@jeromevdl jeromevdl added enhancement New feature or request help wanted Extra attention is needed size/XXL triage RFC feature-parity Feature parity with python version labels Mar 20, 2023
@jeromevdl
Copy link
Contributor Author

Note that we can also handle the APIGatewayV2HTTPEvent in the same way.

@jeromevdl
Copy link
Contributor Author

jeromevdl commented Mar 20, 2023

jax-rs => jakarta-rs, see https://jakarta.ee/specifications/restful-ws/3.1/jakarta-restful-ws-spec-3.1.html
But as we need to be compliant with Java 1.8, we must stay on jax-rs imports and cannot use later version than 2.1.6.

@mriccia
Copy link
Contributor

mriccia commented Mar 21, 2023

I really like this RFC, I agree on the jax-rs/jakarta-rs API compatibility and for me it is a must have. It will enable easy porting of code into Powertools, and the familiar API will reduce the developer friction.
Few questions:

  • Is there also scope to support ALB routing? As it is now possible to use Lambda with ALB, I think this integration would be useful
  • A very common question from customers is: can I write the same code to run in AWS Lambda and in a Container environment (e.g. Fargate). Would we consider supporting this feature?

@jeromevdl
Copy link
Contributor Author

⚠️ JAX-RS is based on reflection, which is slow. As it is intended to be used with API Gateway and supposed to be fast (sync call), it's an important drawback.

Could we use compile-time weaving or annotation preprocessor (code generation)?

@msailes
Copy link
Contributor

msailes commented Mar 21, 2023

I think this is a really exciting idea. Lots of people are interested in running rest endpoints on Lambda.

If Powertools only supports a subsection of the standard, how can we help users understand whether their application would be supported or not?

Would there be a clear list of features / annotations which were yes / no?

@scottgerring
Copy link
Contributor

scottgerring commented Jul 19, 2023

For the moment we can steer users to existing integrations rather than reinventing the wheel. For instance:

This misses some of the functionality in the powertools for python (e.g. - supporting event from all the different possible sources - REST API GW, HTTP API GW, ALB, Lattice), but I think we should wait to see demand for this first.

@scottgerring scottgerring added blocked Tasks that can't be started yet and removed help wanted Extra attention is needed labels Jul 20, 2023
@scottgerring
Copy link
Contributor

We're actively choosing not to work on this for now and I am marking it as blocked to reflect that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Tasks that can't be started yet enhancement New feature or request feature-parity Feature parity with python version priority:5 Unknown - Idea for later RFC size/XXL
Projects
Development

No branches or pull requests

4 participants