zio-http icon indicating copy to clipboard operation
zio-http copied to clipboard

Reverse Routing for Endpoints or HttpApp

Open gavares opened this issue 3 years ago • 2 comments

Our API returns resource links embedded in response bodies and in Location headers. Some other frameworks provide features which allow for request details such as method, path, and parameters to be derived from the endpoint descriptions which helps ensure that URLs and paths accurately match the service definition.

Examples:

  • Play! provides this by using Reverse Routing
  • In Tapir, the generated SttpClient for the service can be used to construct a request and then extract method, path, and parameters

I imagine that the Endpoint class might be the most natural place to add this feature in zio-http.

This feature would also provide a path for auto-derivation of API clients and, eventually, OpenAPI/Swagger specification.

gavares avatar Jan 04 '22 04:01 gavares

As another example using smithy4s, I can create typesafe reverse routes by writing a bit of code. Assume a service named MyService with an endpoint ListItems. Smithy4s generates an object named MyServiceGen. If the ListItems endpoint has the following signature:

GET /api/v1/items/{groupId}

I can create a ReverseRouter object that let's me write methods like:

import zhttp.http._

object ReverseRouter {

  def listItems(request: ListItemsRequest): Request = {
    Request(
      method = convertMethod(MyServiceGen.ListItems.method),
      url = urlFromString(MyServiceGen.ListItems.path(request)),
  }

  def convertMethod(method: smithy4s.http.HttpMethod): zhttp.http.Method = ...
  def urlFromString(pathStr: String) = URL(basePath / pathStr)
}

And to get a handle to the route in my code:

    val listReq = ReverseRouter.listItems(ListItemsRequest("group1"))

So while my Http handling layer is defined by hand using zio-http, I can use the generated code from the smithy4s library to construct my reverse routes.

In this scenario, native reverse routing by zio-http would save me having to create and maintain the ReverseRouter class.

gavares avatar Jan 06 '22 17:01 gavares

@gavares Could you elaborate on your use case? From what you have posted, I could figure out that we need a native way to define a service* to request generation.

Could you maybe give some specs on what you are imaging the API to be like?

girdharshubham avatar Feb 02 '22 06:02 girdharshubham

I am going to close this for now, as Endpoint is very well-developed and has lots of features related to this one.

jdegoes avatar Mar 17 '23 23:03 jdegoes