Sam
06/19/2023, 4:21 PMEndpoint
but not sure I'm happy with thatswishy
06/19/2023, 9:13 PMSam
06/19/2023, 9:44 PMribesg
06/20/2023, 8:33 AMresource
package with resources (`data class`es and `object`s annotated with @Resource
) and a route
package with the route definitions. The MyResource
files contain everything data: the resource, the @Serializable
payload if any, the @Serializable
response if any, and OpenAPI definitions using tegral-openapi-ktor-resources
. The MyRoute
files contain a single function: fun Routing.setupMyRoute()
which starts with some dependency injection using Koin and then usually a single endpoint definition (rarely more than one, sometimes I can have multiple verbs for the exact same resource).
I have no issue having separate resources for the same path, for exemple I could have a @Resource("/v1/user/{userId}") GetUserResource(val userId: String)
and a @Resource("/v1/user/{userId}") DeleteUserResource
with a GetUserRoute
implementing the retrieval of a user and DeleteUserRoute
implementing the deletion of a user: I prefer more files with less coderibesg
06/20/2023, 8:35 AM@Resource
annotation references a full path.ribesg
06/20/2023, 8:39 AMresource
package, I have v0
, v1
, v2
packages (v0
is old unversioned endpoints), but not in my route
package. For example, I could have an old v0/GetUserResource
and a more recent v2/GetUserResource
and implement both in a single GetUserRoute
file, usually with an internal redirection using something like this:
suspend inline fun <reified T : Any> ApplicationCall.redirectInternally(resource: T) {
val path = application.href(resource)
val connectionPoint = object : RequestConnectionPoint by request.local {
override val uri get() = path
}
val request = object : ApplicationRequest by request {
override val local get() = connectionPoint
}
val call = object : ApplicationCall by this {
override val request get() = request
}
application.execute(context = call, subject = Unit)
}
Sam
06/20/2023, 8:47 AMswishy
06/20/2023, 8:50 AMribesg
06/20/2023, 8:51 AMribesg
06/20/2023, 8:52 AMswishy
06/20/2023, 8:53 AMribesg
06/20/2023, 8:54 AMribesg
06/20/2023, 8:54 AMSam
06/20/2023, 8:54 AMribesg
06/20/2023, 8:55 AMswishy
06/20/2023, 8:58 AMswishy
06/20/2023, 8:59 AMswishy
06/20/2023, 9:01 AMswishy
06/20/2023, 9:01 AMswishy
06/20/2023, 9:05 AMribesg
06/20/2023, 9:06 AM/v1/
and /v2/
just exist in this project. I'm rewriting the entire thing in a better, modern way, but I can't change paths or functionality. I just need to set a standard for our Kotlin APIs and spread it, and hopefully our developers will know what to do by just mimicking what exists in the futurribesg
06/20/2023, 9:07 AMv1
endpoint which matches a similar v2
endpoint, but the v2
endpoint takes an additional, mandatory locale
parameter, so the v1
redirects to v2
with a default valueswishy
06/20/2023, 9:07 AM