Skip to content

Repository files navigation

CallableKit

CallableKit provides typesafe rpc with Swift server.

Supported server frameworks

Supported clients

  • Swift (with Foundation)
  • TypeScript (with fetch)

Usage

Define interface protocol and share the module to server and client. Interface protocols must be annotated with @Callable

import CallableKit
@CallablepublicprotocolEchoServiceProtocol{func hello(request:EchoHelloRequest)asyncthrows->EchoHelloResponse}publicstructEchoHelloRequest:Codable,Sendable{publicinit(name:String){self.name = name
}publicvarname:String}publicstructEchoHelloResponse:Codable,Sendable{publicinit(message:String){self.message = message
}publicvarmessage:String}

On the server side, you prepare the implementation of the protocol and register it for routing using the Transport module.

import APIDefinition // Your interface module
import CallableKitVaporTransport
import Vapor
structEchoService:EchoServiceProtocol{func hello(request:EchoHelloRequest)asyncthrows->EchoHelloResponse{return.init(message:"Hello, \(request.name)!")}}letapp=tryawaitApplication.make()
// Swift macro generates `configureEchoServiceProtocol`
configureEchoServiceProtocol(transport:VaporTransport(router: app.routes){ _ inEchoService()})tryawait app.execute()tryawait app.asyncShutdown()

Client can call the functions through a stub client.

import APIDefinition
import CallableKitURLSessionStub
letstubClient:someStubClientProtocol=URLSessionStubClient(
baseURL:URL(string:"http://127.0.0.1:8080")!
)
// EchoServiceProtocolStub is also generated by Swift macro
letechoClient=EchoServiceProtocolStub(client: stubClient)letres=tryawait echoClient.hello(request:.init(name:"Swift"))print(res.message) // Hello, Swift!

TypeScript client is also supported. It needs manual code generation.

conststub=createStubClient("http://127.0.0.1:8080");constechoClient=bindEcho(stub);constres/*: { message: string }*/=awaitechoClient.hello({name: "TypeScript"});console.log(res.message);// Hello, TypeScript!

Swift types are coverted to TypeScript types powered by CodableToTypeScript

Run code generation

$ swift run codegen Sources/APIDefinition \
--ts_out TSClient/src/Gen

Mint is useful to checkout and run.

or

  • Use from package plugin (see example)

    Add plugin target in your Package.swift (or add dedicated Package.swift for independency)

dependencies:[....package(url:"https://github.com/sidepelican/CallableKitCodegen.git", from:"1.0.0"),],targets:[....plugin(
name:"CodegenPlugin",
capability:.command(
intent:.custom(verb:"codegen", description:"Generate codes from Sources/APIDefinition"),
permissions:[.writeToPackageDirectory(reason:"Place generated code")]),
dependencies:[.product(name:"codegen",package:"CallableKitCodegen"),]),]
swift run codegen

About

Typesafe rpc with Swift server

Resources

Stars

3 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages