zio-http
zio-http copied to clipboard
Reverse Routing for Endpoints or HttpApp
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.
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 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?
I am going to close this for now, as Endpoint
is very well-developed and has lots of features related to this one.