Routing
Like many RPC systems, our routing is based around the idea of defining an endpoint, specifying the methods that can be called remotely with their parameters and return types. We use data transfer object classes (DTO) in the common Kotlin module as the Interface Definition Language (IDL) for describing both the endpoint interface and the structure of the payload messages.
@JsExport
object HelloWorldEndPoint :
EndPoint<HelloWorldEndPoint.Request, HelloWorldEndPoint.Response>() {
class Request(
val data: String? = null,
)
class Response(
val data: String? = null,
)
}
Then, you have to specify the end point on the common routing DSL.
object Routing {
//...
fun init() = api {
"api" {
"v1" {
"hello_world" {
route(HelloWorldEndPoint)
}
}
}
}
//...
}
Finally, you have create the endpoint Handler in the JVM module
@CommonHandler
class HelloWorldController :
EndpointHandler<HelloWorldEndPoint.Request, HelloWorldEndPoint.Response>(
HelloWorldEndPoint.Request::class,
HelloWorldEndPoint
) {
override fun process(
requestDto: HelloWorldEndPoint.Request,
clientData: AuthorizedClientData?,
): DataResponse<HelloWorldEndPoint.Response> {
return DataResponse(
HelloWorldEndPoint.Response(data = "You sent: ${requestDto.data}")
)
}
}
Now, you can call the endpoint from the JS module using an extension function called remote
val mainScope = MainScope()
fun main() {
mainScope.launch {
val response = HelloWorldEndPoint.remoteProcess(HelloWorldEndPoint.Request(data = "Hi!"))
println(response.data)
//output: "You sent: Hi!"
}
}
Advance example
object Routing {
//...
fun init() = api {
"api" {
"v1" {
"users" {
require(Privilege.UsersManagement)
"hello_world" {
route(HelloWorldEndPoint)
}
}
}
}
}
//...
}
Advance example
Routing:
api {
"api" {
"v1" {
"admin" {
require(Privilege.UsersManagement)
"staff" {
crud(StaffCrudEndPoint)
"enable_staff" {
route(StaffEnableEndPoint)
}
}
"talents" {
"enable_talent" {
route(TalentEnableEndPoint)
}
}
}
"companies" {
"users" {
crud(UsersCrudCompaniesEndPoint) {
enableOnly(ListEndpoint, DetailsEndpoint)
}
}
}
}
}
}
End-Points:
@JsExport object UsersCrudAdminEndPoint : CrudEndPoint<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>()
@JsExport object UsersCrudCompaniesEndPoint : CrudEndPoint<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>()
@JsExport
object UsersCrudEndPoint : CrudEndPoint<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>() {
class Request(
val id: StringUUID? = null,
val name: String? = null,
)
class Filters(
val data: String? = null,
)
}
Endpoint crud controller:
@CommonHandler
class UsersEndpointCrudController : EndpointCrudController<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>(
listOf(UsersCrudEndPoint, UsersCrudAdminEndPoint, UsersCrudCompaniesEndPoint),
UsersCrudEndPoint.Request::class,
UsersCrudEndPoint.Filters::class
) {
//...
}
Client calls:
val mainScope = MainScope()
fun main() {
mainScope.launch {
val addResponse = UsersCrudEndPoint.remoteAdd(UsersCrudEndPoint.Request(TODO()))
val updatePesponse = UsersCrudEndPoint.remoteUpdate(UsersCrudEndPoint.Request(TODO()))
val detailsPesponse = UsersCrudEndPoint.remoteDetails(UsersCrudEndPoint.Request(TODO()))
val listPesponse = UsersCrudEndPoint.remoteList(CrudDto.GetList.Request(TODO()))
val deletePesponse = UsersCrudEndPoint.remoteDelete(UsersCrudEndPoint.Request(TODO()))
}
}
No Comments