How to wrap the service inside authenticate{}?
Aditya94A opened this issue · 8 comments
I'd like to use io.ktor.auth
's authentication and just stick the implementation of ktor-retrofit Service inside the authenticate{}
block.
What's the recommended way to do this?
Something like this?
authenticate("myService") {
install(RetrofitService) {
service(service = MyService)
}
}
This doesn't look right and for having multiple services I'll need to do install()
multiple times. What's the right way?
As currently designed, RetrofitService
is a Feature
which directly attaches routings into the application. This bypasses any authentication configuration unless they somehow play nice together in the backend.
If you wanted to experiment you could try something like:
install(RetrofitService) {
service(service = MyService)
}
routing {
route(baseUrl) {
authenticate("myService") {}
}
}
Which may install the authentication into the same routing that the RetrofitService
feature sets up.
However, I'm now wondering if a better design for ktor-retrofit
might be something like the following:
routing {
route(baseUrl) {
service(service = MyService)
}
}
Where service(...)
is an extension on the routing DSL rather than an application feature.
Yeah, tried all the methods, nothing works.
That second code snippet you posted looks perfect. Is there a way to make it happen? Maybe by offering an additional add-on dependency to ktor-retrofit (or even in the same one as auth and routing are so common)?
I've released version 0.1.1
with support for the following DSL:
routing {
route(baseUrl) {
retrofitService(service = MyService)
}
}
I've updated the README with the new recommend way to inject Retrofit service implementations. Let me know if you encounter any more issues! I'm excited someone is actually using this crazy idea of a library.
Nice, will give it a shot.
I have this crazy idea of making my android app and backend entirely in kotlin (and maybe iOS/JavaScript business logic too with kotlin native).
So I have this whole common git submodule setup with common data classes for requests/responses, the API interfaces inside the common submodule as well as API interfaces using inheritance so that the same API describes interaction between server <> client as well as microservice <> microservice <>.
- One common module for all kotlin projects (with common kotlin/java utils)
- Another common module for all kotlin android apps (with common android utils)
- Another common module for all kotlin backend microservices (with common backend utils)
- Another common module for project specific stuff across a project (with business logic)
So using ktor-retrofit would fit in very nicely in my architecture, allowing me to describe a specific API just ONCE in my entire project. Makes full-stack dev dead simple.
@AdityaAnand1 , has this been working for you? Let me know if you have any further problems.
Hmmm, I think I may be running into an unrelated issue.
I use Response wrapped response structure everywhere in my services (for error handling) so it looks like:
interface Service {
@GET("string")
suspend fun getAll(): Response<List<String>>
@GET("string/{id}")
suspend fun getSingle(@Path("id") id: Long): Response<String>
}
And then in the ktor-retrofit service implementation, I then return a
return Response.success(myResponseObj)
But for some reason, my responses are not transmitted if implemented this way, here's a snippet of the response when hitting a ktor-retrofit implemented endpoint (logged via HttpLoggingInterceptor):
Vary: Origin
Content-Type: application/json; charset=UTF-8
Connection: keep-alive
transfer-encoding: chunked
{}
<-- END HTTP (2-byte body)
Notice the empty {}
The service is installed as:
routing {
route("/") {
authenticate(AuthLabel) {
retrofitService(service = MyService)
}
Also, returning a Response.error(..)
doesn't seem to work, it still sends the same 200 empty response anyways.
It's trying to serialize the whole Response instance. Right now ktor-retrofit
doesn't support unwrapping Response instance as part of the installed service.
If this is something you need to use this library open another issue and in the meantime I will start looking into what it will take to support.