KsMethod

annotation class KsMethod(val name: String)

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
}

Properties

Link copied to clipboard