Clarify the design and plans for the HTTP feature
cb372 opened this issue · 2 comments
Mu currently has the following in the way of HTTP (i.e. not gRPC) support:
- An
@http
annotation that can be added to methods in service traits. This results in the@service
macro generating some http4s-specific server and client (?) code. This whole feature is undocumented and I'm not sure what its status is. The long discussion on #583 is the most useful historical record I've found so far. - Support for generating http4s+circe client code from an OpenAPI YAML file. This feature is documented, but it has some known issues: the generated code is not hygienic so you can get compilation errors due to name clashes.
These two features seem to have been built independently and I'm not sure how they fit together into a larger plan. I'd like to clarify this, document it and start building whatever is missing.
Yeah, there are two independent developments: server and client.
- Server: it's scala driven based on annotations. The users need to write the scala code by themselves, using the available annotations. This HTTP feature might not be ready for using it in production... and probably is not aligned with the rest of the RPC features in terms of code generation from IDL specs.
- Client: in this case, despite the issues you have commented, the HTTP client code generation from Open API Specs is aligned with the project spirit, where given a standard definition, you can consume HTTP services using auto-generated clients out of the box.
From my perspective, we would need to re-design/re-write the HTTP feature to make it a single thing. For example, given an OpenAPI spec, mu
can generate the primary routes file, where the implementation corresponds to the final user. If we adopt this direction, we will need to revisit the current annotations. On the other hand, HTTP clients would be created as they are right now, with the needed improvements. Both ends, based on the same Open API specification.
One other thing I noticed about the @http
annotation is that it's quite confusing to have it on the method level instead of the service level. That means you can mix gRPC and HTTP endpoints in one service, and the serialization specified in the @service
annotation only applies to the gRPC endpoints. e.g.
@service(Protobuf) trait MyService[F[_]] {
def gRpcEndpointWithProtobufSerialization(...): F[...]
@http def httpEndpointWithJsonSerialization(...): F[...]
}
I don't think an HTTP service and an RPC service should be mixed together this.