A simple microservices messaging framework for NestJS with Kafka transport. Build scalable distributed systems with type-safe inter-service communication.
Explore Architecture@Injectable()
export class UserService extends KafkaClientBase {
constructor(@Inject("NEVO_KAFKA_CLIENT") client: NevoKafkaClient) {
super(client)
}
async getByEmail(email: string) {
return { id: 42n, name: "Eddie", email }
}
async delete(id: bigint) {
await this.emit("coordinator", "user.deleted", { userId: id })
return { success: true, deletedId: id }
}
}
@Controller()
@KafkaSignalRouter([UserService])
export class UserController {
@Signal("user.getByEmail", "getByEmail", (data: any) => [data.email])
getUserByEmail() {}
@Signal("user.delete", "delete", (data: any) => [data.id])
deleteUser() {}
@Signal("auth.sendMagicLink", "sendMagicLink")
sendMagicLink() {}
}
// Query pattern (request-response)
const user = await this.query("user", "user.getByEmail", {
email: "eddie@example.com"
})
// Emit pattern (fire-and-forget)
await this.emit("notifications", "user.created", {
userId: user.id,
email: user.email
})
@Module({
providers: [
UserService,
createNevoKafkaClient(["COORDINATOR", "WALLET"], {
clientIdPrefix: "user",
timeoutMs: 25000,
debug: true
})
]
})
export class UserModule {}
Declarative method mapping with @Signal decorator. Clean, intuitive API that makes microservice communication a breeze.
Full TypeScript support with auto-completion. Catch errors at compile time, not runtime.
Both request-response (query) and fire-and-forget (emit) patterns. Use the right tool for the job.
Handle large integers seamlessly across service boundaries. Suitable for financial and scientific applications.
Comprehensive error handling, lifecycle hooks, timeout management, and production-grade reliability.
Automatic topic creation, client setup, and service discovery. Get up and running in minutes.