Skip to main content

TypeScript Server Reference

AsterServer

The high-level server wrapper that handles service registration, endpoint creation, and health endpoints.

import { AsterServer } from '@aster-rpc/aster';
import { HelloService } from './service.js';

const server = new AsterServer({
services: [new HelloService()],
config: {
logFormat: 'json',
},
});

await server.start();
console.log("Producer ready at:", server.address);
await server.serve(); // blocks until shutdown

Options

OptionTypeDefaultDescription
servicesobject[]RequiredArray of @Service-decorated instances
configPartial<AsterConfig>{}Override config values
identitystringundefinedPath to a .aster-identity TOML file
peerstringundefinedPeer name to load from the identity file
allowAllConsumersbooleantrueOpen-gate mode (dev). Set false for trusted mode.
interceptorsInterceptor[][]Server-side interceptors

Methods

MethodReturnsDescription
start()Promise<void>Start the server (create node, publish contracts, open admission)
serve()Promise<void>Block until the server is shut down (Ctrl+C in scripts)
close()Promise<void>Graceful shutdown
localTransport()LocalTransportIn-process transport for testing

Properties

PropertyTypeDescription
addressstringaster1... ticket consumers connect to
runningbooleanWhether the server is running
registryServiceRegistryThe service registry
configAsterConfigResolved configuration

ServiceRegistry

import { ServiceRegistry, LocalTransport } from '@aster-rpc/aster';
import { HelloService } from './service.js';

const registry = new ServiceRegistry();
registry.register(new HelloService());

const transport = new LocalTransport(registry);

Methods

MethodReturnsDescription
register(instance)ServiceInfoRegister a @Service-decorated instance
lookup(name, version?)ServiceInfo | undefinedLook up by name and optional version
lookupMethod(service, method)[ServiceInfo, MethodInfo] | undefinedLook up a specific method
services()IterableIterator<ServiceInfo>All registered services
sizenumberNumber of registered services

Decorators

@Service

@Service({ name: "Echo", version: 1 })
class EchoService { ... }

@Rpc

@Rpc({ timeout: 30, idempotent: true })
async echo(req: EchoRequest): Promise<EchoResponse> { ... }

The aster-gen build step reads request/response types from the AST, so you don't need to pass them in the decorator. Optional keys: timeout, idempotent, requires, serialization. See TypeScript Build Setup.

@ServerStream

@ServerStream()
async *watchItems(req: WatchRequest): AsyncGenerator<ItemUpdate> { ... }

@ClientStream

@ClientStream()
async uploadBatch(requests: AsyncIterable<Item>): Promise<BatchResult> { ... }

@BidiStream

@BidiStream()
async *chat(requests: AsyncIterable<Message>): AsyncGenerator<Message> { ... }

@WireType

@WireType("myapp/Invoice")
class Invoice {
amount = 0;
currency = "USD";
constructor(init?: Partial<Invoice>) { if (init) Object.assign(this, init); }
}

Interceptors

All 9 interceptors from the Python binding are available:

import {
DeadlineInterceptor,
MetricsInterceptor,
RetryInterceptor,
RateLimitInterceptor,
AuthInterceptor,
CircuitBreakerInterceptor,
CompressionInterceptor,
AuditLogInterceptor,
CapabilityInterceptor,
} from '@aster-rpc/aster';

const metrics = new MetricsInterceptor();
const rateLimit = new RateLimitInterceptor({ globalRps: 1000, perServiceRps: 500 });

See the Python Server Reference for detailed interceptor documentation — the TypeScript API mirrors it exactly.