BaseAdminRoute
BaseAdminRoute gives trusted users a set of common administrative actions over the running service: clearing the cache, tailing logs live, reading
release notes, and triggering a restart.
import { BaseAdminRoute, RouteDecorators } from "@rapidrest/service-core";
const { Route } = RouteDecorators;
@Route("/admin")
export class AdminRoute extends BaseAdminRoute {}
The CLI scaffold generates exactly this at src/routes/AdminRoute.ts, mounted at /admin.
Endpoints
| Function | HTTP Method + Path | What it does |
|---|---|---|
clearCache | GET /admin/clear-cache | Flushes the Redis-based second-level cache. |
logs | UPGRADE /admin/logs | Opens a WebSocket that live-tails the service's log output. |
getReleaseNotes | GET /admin/release-notes | Returns the service's release notes. |
restart | GET /admin/restart | Signals the service to restart. |
Every endpoint requires @Auth(["jwt"]), and clearCache, getReleaseNotes and restart additionally require the caller to hold one of the roles
listed in trusted_roles. There is no way to reach them anonymously.
Configuration
conf.defaults({
service_name: 'petstore',
trusted_roles: ['admin'],
datastores: {
cache: {type: 'redis', host: 'localhost', port: 6379},
logs: {type: 'redis', host: 'localhost', port: 6379},
},
});
clearCacheonly does anything useful if acachedatastore is configured. It scans and deletes keys matchingdb.cache.*on that connection.logsrequires alogsdatastore. On startup,BaseAdminRouteattaches a Winston transport (RedisTransport) that publishes every log line to a<service_name>-logsRedis channel; the WebSocket endpoint subscribes to that same channel and forwards messages to the connected client. Iflogsisn't configured, the route logs a warning at startup and the endpoint closes any connection attempt.restartpublishes aRESTARTmessage on a<service_name>(orservice_admin, ifservice_nameis unset) channel over thecacheconnection.BaseAdminRoutealso subscribes to that same channel on startup, so any instance sharing that Redis connection (including the one that issued the request) will receive the signal and callprocess.kill(process.pid, "SIGINT")on itself. In a multi-instance deployment behind a shared Redis, a single/admin/restartcall restarts every instance listening on that channel.
Locking it down further
Because AdminRoute is a normal class in your project, you can tighten access beyond trusted_roles. For example, mount it on a different base
path that's only reachable from an internal network, or override trustedRoles to a narrower list:
@Route("/internal/admin")
export class AdminRoute extends BaseAdminRoute {
protected trustedRoles: string[] = ['superadmin'];
}