KsMethod
Tags a method within a KsService for rpc calls.
The name must be unique within a KsService but need not be unique globally.
A @KsMethod may return Result<O>. Such a method is equivalent to a plain O-returning method wrapped in runCatching-except-cancellation: success yields Result.success(o), a thrown or returned failure yields Result.failure(e), and the stub does not throw except for cancellation. The wire format is unchanged — success serializes the inner O and failure uses the existing KsError / error envelope; kotlin.Result is never serialized.
Samples
import com.monkopedia.ksrpc.RpcService
import com.monkopedia.ksrpc.annotation.KsMethod
import com.monkopedia.ksrpc.annotation.KsService
import com.monkopedia.ksrpc.ksrpcEnvironment
import com.monkopedia.ksrpc.rpcObject
import com.monkopedia.ksrpc.serialized
import com.monkopedia.ksrpc.toStub
import kotlinx.serialization.Serializable
fun main() {
//sampleStart
// Define a service interface with @KsService and @KsMethod annotations.
// The compiler plugin generates a companion RpcObject and stub automatically.
val rpcObj = rpcObject<GreetingService>()
val endpoint = rpcObj.findEndpoint("greet")
//sampleEnd
}import com.monkopedia.ksrpc.RpcService
import com.monkopedia.ksrpc.annotation.KsMethod
import com.monkopedia.ksrpc.annotation.KsService
import com.monkopedia.ksrpc.ksrpcEnvironment
import com.monkopedia.ksrpc.rpcObject
import com.monkopedia.ksrpc.serialized
import com.monkopedia.ksrpc.toStub
import kotlinx.serialization.Serializable
fun main() {
//sampleStart
// Any @Serializable class can be used as input or output to @KsMethod.
// The compiler plugin handles serializer plumbing automatically.
val rpcObj = rpcObject<UserService>()
val endpoint = rpcObj.findEndpoint("create")
//sampleEnd
}import com.monkopedia.ksrpc.RpcService
import com.monkopedia.ksrpc.annotation.KsMethod
import com.monkopedia.ksrpc.annotation.KsService
import com.monkopedia.ksrpc.ksrpcEnvironment
import com.monkopedia.ksrpc.rpcObject
import com.monkopedia.ksrpc.serialized
import com.monkopedia.ksrpc.toStub
import kotlinx.serialization.Serializable
fun main() {
//sampleStart
// Methods can omit the parameter (returns Unit) or the return type.
// suspend fun ping(): String -- no input
// suspend fun notify(message: String) -- no output (returns Unit)
val rpcObj = rpcObject<PingService>()
//sampleEnd
}import com.monkopedia.ksrpc.RpcService
import com.monkopedia.ksrpc.annotation.KsError
import com.monkopedia.ksrpc.annotation.KsMethod
import com.monkopedia.ksrpc.annotation.KsService
import com.monkopedia.ksrpc.ksrpcEnvironment
import com.monkopedia.ksrpc.serialized
import com.monkopedia.ksrpc.toStub
import kotlinx.serialization.Serializable
fun main() {
//sampleStart
// A Result<O> method is equivalent to a plain O method wrapped in
// runCatching-except-cancellation. The wire format is unchanged: success
// serializes the inner O, and failure uses the same @KsError / error
// envelope as a thrown exception. kotlin.Result is never serialized.
val service = object : ParseService {
override suspend fun parse(input: String): Result<Int> =
input.toIntOrNull()?.let { Result.success(it) }
?: Result.failure(ParseError(input))
}
//sampleEnd
}import com.monkopedia.ksrpc.RpcService
import com.monkopedia.ksrpc.annotation.KsError
import com.monkopedia.ksrpc.annotation.KsMethod
import com.monkopedia.ksrpc.annotation.KsService
import com.monkopedia.ksrpc.ksrpcEnvironment
import com.monkopedia.ksrpc.serialized
import com.monkopedia.ksrpc.toStub
import kotlinx.serialization.Serializable
fun main() {
//sampleStart
val service = object : ParseService {
override suspend fun parse(input: String): Result<Int> =
input.toIntOrNull()?.let { Result.success(it) }
?: Result.failure(ParseError(input))
}
val env = ksrpcEnvironment { }
val serialized = service.serialized(env)
val stub = serialized.toStub<ParseService, String>()
// The stub returns a Result and does NOT throw on failure. A failure
// mapped via @KsError round-trips as Result.failure(typedError).
stub.parse("42")
.onSuccess { value -> println("Parsed $value") }
.onFailure { error -> println("Failed: ${error.message}") }
val outcome: Result<Int> = stub.parse("not-a-number")
// outcome.isFailure == true; outcome.exceptionOrNull() is a ParseError.
//sampleEnd
}