Skip to main content

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.

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

fun main() {
    GlobalScope.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:

 


object UsersCrudAdminEndPoint : CrudEndPoint<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>()
object UsersCrudCompaniesEndPoint : CrudEndPoint<UsersCrudEndPoint.Request, UsersCrudEndPoint.Filters>()

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:

fun main() {
    GlobalScope.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()))
    }
}