Functions in a remote interface are just regular functions in Kotlin that, when connected to a Web Frame, can be invoked from the web layer.
Examples
Functions can be declared any number of ways. The following examples are for a remote function that responds with the data that is sent to it from the web layer.
Declared as a function
fun echo(call: Call) {
call.respond(call.request.data)
}
Declared as a method within a class
class Echo {
fun echo(call: Call) {
call.respond(call.request.data)
}
}
Declared as a lambda
functions = mapOf(
"echo" to { call ->
call.respond(call.request.data)
},
),
Web Frame Configuration
For the following example, we’ll be using a function declared like the following:
fun echo(call: Call) {
call.respond(call.request.data)
}
Since functions have first-class support in Kotlin, we can pass them as references to the Web Frame configuration.
val configuration = WebFrame.Configuration(
baseUrl: ...
functions = mapOf(
"echo" to ::echo,
),
observables = emptyMap(),
)
Peregrine expects remote functions to match the following type in Kotlin.
typealias RemoteFunction = (Call) -> Unit
Android API
Call
An instance of the Call
class represents a single invocation of a remote
function.
Properties
val request: Request
The Request
instance associated with this call.
Methods
fun respond()
Complete the call by responding with empty data.
fun respond(text: String)
Complete the call by responding with a UTF-8 encoded string.
fun respond(data: JsonElement)
Complete the call by responding with arbitrary data.
Data must be JSON content on Android. One delightful way of creating arbitrary
JSON content is by using the
buildJsonObject
helper from the KotlinX Serialization library:
call.respond(buildJsonObject {
put("width", 100)
put("height", 100)
})
inline fun <reified T> respond(json: T)
Complete the call by responding with a serializable object.
The easiest way to make a class serializable is by annotating it with
@Serializable
from the KotlinX Serialization library:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class SizeResponse(val width: Double, val height: Double)
Then, objects can be passed to .respond()
directly:
call.respond(SizeResponse(100, 100))
This function uses
Json.encodeToJsonElement
under the hood to serialize almost any data type: strings, booleans, ints,
doubles, as well as any instances of classes annotated with @Serializable
. For
more information, see the docs for
KotlinX Serialization.
fun fail(message: String = "Error", code: String? = null)
Complete the call (marking it as failed) by responding with an error message and code.
This will cause the web client to throw a ClientError
exception.
Request
Contains the request data from the web layer and helpers to extract it.
Properties
val data: JsonElement
The raw data from the web layer.
val text: String
The data decoded as a UTF-8 string.
Methods
inline fun <reified T> json(): T
The data converted to a serializable object.
Annotate classes with @Serializable
:
@Serializable
data class SizeRequest(
val name: String
)
Then, pass the type as a generic parameter to .json()
:
val sizeRequest = call.request.json<SizeRequest>()
val shapeName = sizeRequest.name
This function uses
Json.decodeFromJsonElement
under the hood to deserialize into almost any data type.