-
Notifications
You must be signed in to change notification settings - Fork 131
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
Decoupling API handler traits from server routes? #233
Comments
For context here: we tend to organize our services as a few gradle modules (subprojects). For example, given a Hello service specified in either protobuf or swagger, we would have approximately the following gradle modules:
I noticed today that our guardrail-based services were pulling in akka-http and friends in the service module, hence the question above. |
No objections, especially considering that split was required to support Java classes. One challenge is that Unifying these features isn't a bad idea, just explaining why it doesn't exist today. I don't know that much about how Do you have any thoughts around this? |
Having a handler that expects If Async isn't the right abstraction, guardrail could define its own trait Scheduler[F[_]] {
def run[T](asyncWork: F[T])(implicit ec: ExecutionContext): Future[T]
} Though I don't know if Scheduler would be an appropriate name for that. |
That seems reasonable; so, the constraint of This would go a long way towards the goal. One other hurdle that would need to be overcome is currently, the frameworks generated are
... coupled with another config change to specify:
I'd be interested to hear how you'd like to consume this in your project configuration |
Oh, I should have looked before I asked. I just saw that trait StoreHandler[F[_]] {
def getRoot(respond: GetRootResponse.type)(): F[GetRootResponse]
def getFoo(respond: GetFooResponse.type)(): F[GetFooResponse]
def getFooDir(respond: GetFooDirResponse.type)(): F[GetFooDirResponse]
} so this is already how http4s works, we'd just need to adapt akka-http's |
Maybe we don't even need to run the generator twice. If the akka-specific code goes into one directory and the handler trait + definition classes go elsewhere (for instance as different java/scala packages), then gradle/sbt/bazel users can compile them as separate modules by setting different source directory patterns. For example in gradle: hello/swagger/build.gradle.kts val generatedPackageName = "com.yourproject.hello.api"
val guardrail = configurations.create("guardrail")
dependencies.add("guardrail", "com.twilio:guardrail_2.12:0.46.0")
val generate = tasks.register("generate", JavaExec::class) {
inputs.files(project.file(specPath))
outputs.dir(generatedSrcDir)
main = "com.twilio.guardrail.CLI"
classpath = guardrail
args = listOf(
"--defaults", "--import", "scala.language.higherKinds", "--import", "akka.NotUsed", "--server",
"--specPath", specPath, "--outputPath", generatedSrcDir,
"--packageName", generatedPackageName)
} hello/interface/build.gradle.kts plugins {
scala
`java-library`
}
dependencies {
api(thirdParty.circeCore)
}
// compile the handler trait and definitions
java {
sourceSets {
this.getByName("main") {
// https://github.com/gradle/kotlin-dsl/issues/650
withGroovyBuilder {
"scala" {
"srcDir"("../swagger/build/generated")
"include"("**/definitions/**")
"include"("**/*Handler.scala")
}
}
}
}
}
tasks.named("scalaCompile").configure { dependsOn(":hello:swagger:generate") } hello/routes/build.gradle.kts plugins {
scala
`java-library`
}
dependencies {
api(thirdParty.akka_http)
}
// compile the akka-http routes, implicits, etc
java {
sourceSets {
this.getByName("main") {
// https://github.com/gradle/kotlin-dsl/issues/650
withGroovyBuilder {
"scala" {
"srcDir"("../swagger/build/generated")
"include"("**/akka/**")
}
}
}
}
}
tasks.named("scalaCompile").configure { dependsOn(":hello:swagger:generate") } |
Generally speaking, I feel that separation of Handler as it is generated for http4s can be adapted for akka quite easily. Your akka server would just require |
Guardrail generates a Handler trait and akka-http server routes in the same file. Would it make sense to decouple them so that a handler implementation could be used for either akka-http, http4s, or any other HTTP server?
The text was updated successfully, but these errors were encountered: