@open-rlb/nestjs-amqp 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/amqp-lib/config/rabbitmq.config.d.ts +6 -0
- package/modules/acl/const.d.ts +0 -1
- package/modules/acl/const.js +0 -1
- package/modules/acl/const.js.map +1 -1
- package/modules/acl/models.d.ts +5 -7
- package/modules/acl/repository/acl-action.repository.d.ts +1 -5
- package/modules/acl/repository/acl-action.repository.js.map +1 -1
- package/modules/acl/repository/acl-role.repository.d.ts +1 -5
- package/modules/acl/repository/acl-role.repository.js.map +1 -1
- package/modules/acl/services/acl-management.service.d.ts +2 -2
- package/modules/acl/services/acl-management.service.js +17 -20
- package/modules/acl/services/acl-management.service.js.map +1 -1
- package/modules/acl/services/acl.service.d.ts +1 -2
- package/modules/acl/services/acl.service.js +5 -21
- package/modules/acl/services/acl.service.js.map +1 -1
- package/modules/broker/broker.module.d.ts +2 -4
- package/modules/broker/broker.module.js +23 -5
- package/modules/broker/broker.module.js.map +1 -1
- package/modules/broker/config/decorator-paths.d.ts +1 -0
- package/modules/broker/config/decorator-paths.js +34 -4
- package/modules/broker/config/decorator-paths.js.map +1 -1
- package/modules/broker/config/route-discovery.config.d.ts +2 -0
- package/modules/broker/const.d.ts +1 -0
- package/modules/broker/const.js +2 -1
- package/modules/broker/const.js.map +1 -1
- package/modules/broker/decorators/broker-action.decorator.d.ts +2 -1
- package/modules/broker/decorators/broker-action.decorator.js +2 -2
- package/modules/broker/decorators/broker-action.decorator.js.map +1 -1
- package/modules/broker/services/broker.service.js +1 -1
- package/modules/broker/services/broker.service.js.map +1 -1
- package/modules/broker/services/metadata-scanner.service.js +11 -2
- package/modules/broker/services/metadata-scanner.service.js.map +1 -1
- package/modules/broker/services/route-discovery-publisher.service.js +7 -5
- package/modules/broker/services/route-discovery-publisher.service.js.map +1 -1
- package/modules/gateway-admin/config/gateway-admin.config.d.ts +4 -0
- package/modules/gateway-admin/const.d.ts +1 -1
- package/modules/gateway-admin/const.js +1 -1
- package/modules/gateway-admin/const.js.map +1 -1
- package/modules/gateway-admin/gateway-admin.module.d.ts +7 -1
- package/modules/gateway-admin/gateway-admin.module.js +13 -0
- package/modules/gateway-admin/gateway-admin.module.js.map +1 -1
- package/modules/gateway-admin/repository/auth-provider.repository.d.ts +3 -4
- package/modules/gateway-admin/repository/auth-provider.repository.js.map +1 -1
- package/modules/gateway-admin/services/gateway-auth.service.d.ts +3 -4
- package/modules/gateway-admin/services/gateway-auth.service.js +15 -23
- package/modules/gateway-admin/services/gateway-auth.service.js.map +1 -1
- package/modules/gateway-admin/services/gateway-metrics.service.d.ts +3 -0
- package/modules/gateway-admin/services/gateway-metrics.service.js +9 -0
- package/modules/gateway-admin/services/gateway-metrics.service.js.map +1 -1
- package/modules/gateway-admin/services/route-sync.service.d.ts +3 -1
- package/modules/gateway-admin/services/route-sync.service.js +14 -8
- package/modules/gateway-admin/services/route-sync.service.js.map +1 -1
- package/modules/proxy/services/http-handler.service.d.ts +3 -0
- package/modules/proxy/services/http-handler.service.js +27 -3
- package/modules/proxy/services/http-handler.service.js.map +1 -1
- package/package.json +5 -1
- package/schematics/nest-add/files/acl/src/cache/in-memory-acl-store.ts +54 -0
- package/schematics/nest-add/files/acl/src/modules/database/repository/acl.repository.ts +74 -0
- package/schematics/nest-add/files/db-core/src/modules/database/repository/in-memory-collection.ts +122 -0
- package/schematics/nest-add/files/gateway-admin/src/modules/database/repository/gateway.repository.ts +151 -0
- package/schematics/nest-add/files/gateway-admin/src/modules/database/repository/route-sync.repository.ts +15 -0
- package/schematics/nest-add/files/skills/rlb-amqp/SKILL.md +33 -5
- package/schematics/nest-add/files/skills/rlb-amqp/references/config-schema.md +182 -93
- package/schematics/nest-add/files/skills/rlb-amqp/references/gotchas.md +129 -79
- package/schematics/nest-add/files/skills/rlb-amqp-acl/SKILL.md +185 -0
- package/schematics/nest-add/files/skills/rlb-amqp-add-action/SKILL.md +87 -2
- package/schematics/nest-add/files/skills/rlb-amqp-add-route/SKILL.md +82 -19
- package/schematics/nest-add/files/skills/rlb-amqp-add-ws-event/SKILL.md +40 -18
- package/schematics/nest-add/files/skills/rlb-amqp-gateway-admin/SKILL.md +244 -0
- package/schematics/nest-add/files/skills/rlb-amqp-scaffold/SKILL.md +177 -42
- package/schematics/nest-add/index.js +612 -142
- package/schematics/nest-add/index.js.map +1 -1
- package/schematics/nest-add/index.ts +673 -241
- package/schematics/nest-add/init.schema.d.ts +10 -1
- package/schematics/nest-add/init.schema.ts +29 -3
- package/schematics/nest-add/schema.json +37 -8
|
@@ -9,10 +9,83 @@ Read first:
|
|
|
9
9
|
- `.claude/skills/rlb-amqp/references/config-schema.md`
|
|
10
10
|
- `.claude/skills/rlb-amqp/references/gotchas.md`
|
|
11
11
|
|
|
12
|
-
Decide the role: a **microservice** (only `@BrokerAction` handlers
|
|
13
|
-
|
|
12
|
+
Decide the role: a **microservice** (only `@BrokerAction` / `@BrokerHTTP` handlers, no
|
|
13
|
+
HTTP server) or a **gateway** (HTTP/WS exposure in front of microservices). Two paths:
|
|
14
|
+
the `nest add` schematic (fast, patches in place) or manual wiring. Canonical runnable
|
|
15
|
+
examples live under `sample/config-sample/` (`gateway-in-memory`, `gateway-db`,
|
|
16
|
+
`calculator.ms`) — mirror those, not the retired `apps/gateway-2`.
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Path A — `nest add` schematic (preferred)
|
|
21
|
+
|
|
22
|
+
From a NestJS project root:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
nest add @open-rlb/nestjs-amqp
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
It **patches in place** (does not scaffold a new app): edits `src/app.module.ts` and
|
|
29
|
+
`src/main.ts`, creates `src/config/config.loader.ts` + `config/config.yaml`, copies
|
|
30
|
+
RUNNABLE in-memory repositories for the selected features, adds deps, and copies the
|
|
31
|
+
Claude skills.
|
|
32
|
+
|
|
33
|
+
### Interactive flow
|
|
34
|
+
|
|
35
|
+
1. **"Create a gateway (HTTP/WebSocket) configuration? y/N"**
|
|
36
|
+
2. **YES** → checkbox of gateway features:
|
|
37
|
+
- `acl` — `AclModule` + ACL management/grant/check paths
|
|
38
|
+
- `gateway-admin` — `GatewayAdminModule` + DB-managed routes/auth-providers/metrics paths
|
|
39
|
+
- `route-reception` — gateway consumes routes auto-published by microservices
|
|
40
|
+
Then prompts for names (defaults shown): exchange `rlb`, ACL queue `rlb-acl`,
|
|
41
|
+
admin queue `rlb-gateway-admin`, control topic `rlb-gateway-control`,
|
|
42
|
+
route exchange `rlb-route-discovery`, route queue `rlb-route-sync`.
|
|
43
|
+
3. **NO** (plain microservice) → checkbox:
|
|
44
|
+
- `auto-config-publish` — publish this service's `@BrokerHTTP` routes to the gateway
|
|
45
|
+
on boot (adds `broker.routeDiscovery`). Prompts service name + route exchange/queue.
|
|
46
|
+
4. "Copy the Claude skills into .claude/skills? Y/n"
|
|
47
|
+
|
|
48
|
+
### Non-interactive flags (CI / scripted)
|
|
49
|
+
|
|
50
|
+
Passing `--gatewayConfig` or any `--features` skips the prompts; everything else falls
|
|
51
|
+
back to `rlb-*` defaults.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Gateway with ACL + admin + route reception
|
|
55
|
+
nest add @open-rlb/nestjs-amqp \
|
|
56
|
+
--gatewayConfig --features acl --features gateway-admin --features route-reception
|
|
57
|
+
|
|
58
|
+
# Plain microservice that auto-publishes its @BrokerHTTP routes on boot
|
|
59
|
+
nest add @open-rlb/nestjs-amqp \
|
|
60
|
+
--gatewayConfig=false --features auto-config-publish \
|
|
61
|
+
--serviceName my-service --routeExchange rlb-route-discovery --routeQueue rlb-route-sync
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
| Flag | Purpose |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `--gatewayConfig` | `true` = gateway, `false` = microservice (default false non-interactive). |
|
|
67
|
+
| `--features <f>` | Repeatable. Gateway: `acl`, `gateway-admin`, `route-reception`. MS: `auto-config-publish`. |
|
|
68
|
+
| `--exchange` | Main AMQP exchange backing acl/admin queues. Default `rlb`. |
|
|
69
|
+
| `--aclQueue` / `--adminQueue` | Queues backing the fixed `rlb-acl` / `rlb-gateway-admin` topics. |
|
|
70
|
+
| `--controlTopic` | Broadcast control/reload topic. Default `rlb-gateway-control`. |
|
|
71
|
+
| `--routeExchange` / `--routeQueue` | Route-discovery exchange/queue. Defaults `rlb-route-discovery` / `rlb-route-sync` — **must match both publisher and gateway**. |
|
|
72
|
+
| `--serviceName` | Route-publish ownership key + AMQP `connection_name`. Default = project name. |
|
|
73
|
+
| `--skills` | Copy Claude skills. Default `true`; `--skills=false` to skip. |
|
|
74
|
+
|
|
75
|
+
> `app.module.ts` patch is idempotent (keys off `BrokerModule.forRootAsync`). If it can't
|
|
76
|
+
> locate `app.module.ts` / `main.ts` it warns and leaves you the manual wiring below.
|
|
77
|
+
|
|
78
|
+
After scaffolding, edit `config/config.yaml` (fill `<AMQP_URI>` / credentials) and replace
|
|
79
|
+
the `<APP_NAME>` `connection_name` placeholder. Then use `rlb-amqp-add-action` /
|
|
80
|
+
`rlb-amqp-add-route` / `rlb-amqp-add-ws-event` to grow the service.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Path B — manual wiring
|
|
85
|
+
|
|
86
|
+
Mirrors `sample/config-sample/gateway-in-memory` (gateway) and `calculator.ms` (pure MS).
|
|
87
|
+
|
|
88
|
+
### 1. `src/config/config.loader.ts`
|
|
16
89
|
|
|
17
90
|
```ts
|
|
18
91
|
import { readFileSync } from 'fs';
|
|
@@ -20,23 +93,25 @@ import * as yaml from 'js-yaml';
|
|
|
20
93
|
import { join } from 'path';
|
|
21
94
|
|
|
22
95
|
const YAML_CONFIG_FILENAME = 'config/config.yaml';
|
|
96
|
+
|
|
23
97
|
export default () =>
|
|
24
98
|
yaml.load(readFileSync(join(process.cwd(), YAML_CONFIG_FILENAME), 'utf8')) as Record<string, any>;
|
|
25
99
|
```
|
|
26
100
|
|
|
27
|
-
(`js-yaml`
|
|
101
|
+
(`js-yaml` + `@nestjs/config` are deps; the gateway also needs `@nestjs/axios`,
|
|
102
|
+
`@nestjs/platform-ws`, `@nestjs/websockets`, `ws`.)
|
|
28
103
|
|
|
29
|
-
|
|
104
|
+
### 2. `src/app.module.ts`
|
|
30
105
|
|
|
31
106
|
```ts
|
|
32
|
-
import { HttpModule } from '@nestjs/axios';
|
|
107
|
+
import { HttpModule } from '@nestjs/axios'; // gateway only
|
|
33
108
|
import { Module } from '@nestjs/common';
|
|
34
109
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
35
|
-
import {
|
|
36
|
-
|
|
37
|
-
|
|
110
|
+
import {
|
|
111
|
+
AppConfig, BrokerModule, BrokerTopic, RabbitMQConfig,
|
|
112
|
+
GatewayConfig, HandlerAuthConfig, ProxyModule, // gateway only
|
|
113
|
+
} from '@open-rlb/nestjs-amqp';
|
|
38
114
|
import yamlConfig from './config/config.loader';
|
|
39
|
-
// import { MyActionService } from './my-action.service';
|
|
40
115
|
|
|
41
116
|
@Module({
|
|
42
117
|
imports: [
|
|
@@ -45,13 +120,15 @@ import yamlConfig from './config/config.loader';
|
|
|
45
120
|
imports: [ConfigModule],
|
|
46
121
|
inject: [ConfigService],
|
|
47
122
|
useFactory: async (config: ConfigService) => ({
|
|
48
|
-
|
|
49
|
-
|
|
123
|
+
// broker.routeDiscovery (publisher side), when used, lives INSIDE this `broker` block.
|
|
124
|
+
options: config.get<RabbitMQConfig>('broker')!,
|
|
125
|
+
topics: config.get<BrokerTopic[]>('topics')!,
|
|
50
126
|
appOptions: config.get<AppConfig>('app'),
|
|
51
127
|
}),
|
|
52
128
|
}),
|
|
129
|
+
|
|
130
|
+
// --- gateway only: omit ProxyModule + HttpModule for a pure microservice ---
|
|
53
131
|
HttpModule,
|
|
54
|
-
// Gateway: auth-providers + gateway config live in ProxyModule (NOT BrokerModule).
|
|
55
132
|
ProxyModule.forRootAsync({
|
|
56
133
|
imports: [ConfigModule],
|
|
57
134
|
inject: [ConfigService],
|
|
@@ -60,33 +137,59 @@ import yamlConfig from './config/config.loader';
|
|
|
60
137
|
gatewayOptions: config.get<GatewayConfig>('gateway'),
|
|
61
138
|
}),
|
|
62
139
|
providers: [
|
|
63
|
-
//
|
|
140
|
+
// Role-gated paths resolve the caller's roles in-process via this token (NO broker hop):
|
|
141
|
+
// { provide: RLB_GTW_ACL_ROLE_SERVICE, useExisting: AclService }, // required if any path uses `roles`
|
|
142
|
+
// Optional in-proxy per-request metrics hook (independent of gateway.metrics):
|
|
143
|
+
// { provide: RLB_GTW_METRICS_HOOK, useClass: InfluxMetricsHook },
|
|
64
144
|
],
|
|
65
145
|
}),
|
|
66
146
|
],
|
|
67
|
-
providers: [/*
|
|
147
|
+
providers: [/* AppService — your @BrokerAction / @BrokerHTTP handlers */],
|
|
68
148
|
})
|
|
69
149
|
export class AppModule {}
|
|
70
150
|
```
|
|
71
151
|
|
|
72
|
-
>
|
|
152
|
+
> The gateway's `auth-providers` + `gateway` config belong to **`ProxyModule`**, not
|
|
153
|
+
> `BrokerModule`. For ACL add `AclModule.forRoot([...repos], { cache })` and bind
|
|
154
|
+
> `RLB_GTW_ACL_ROLE_SERVICE`; for DB routes/auth/metrics add
|
|
155
|
+
> `GatewayAdminModule.forRoot([...repos])` — see the `gateway-in-memory` sample and the
|
|
156
|
+
> ACL / Gateway Admin docs.
|
|
157
|
+
|
|
158
|
+
### 3. `src/main.ts`
|
|
73
159
|
|
|
74
|
-
|
|
160
|
+
**Gateway** (needs `rawBody` + `WsAdapter`):
|
|
75
161
|
|
|
76
162
|
```ts
|
|
163
|
+
import { ConfigService } from '@nestjs/config';
|
|
77
164
|
import { NestFactory } from '@nestjs/core';
|
|
78
165
|
import { WsAdapter } from '@nestjs/platform-ws';
|
|
79
166
|
import { AppModule } from './app.module';
|
|
80
167
|
|
|
81
168
|
async function bootstrap() {
|
|
82
|
-
const app = await NestFactory.create(AppModule, { rawBody: true }); // rawBody
|
|
83
|
-
app.useWebSocketAdapter(new WsAdapter(app)); //
|
|
84
|
-
|
|
169
|
+
const app = await NestFactory.create(AppModule, { rawBody: true }); // rawBody: raw-body/webhook routes
|
|
170
|
+
app.useWebSocketAdapter(new WsAdapter(app)); // WS events
|
|
171
|
+
app.enableShutdownHooks();
|
|
172
|
+
const cfg = app.get(ConfigService).get<{ port?: number; host?: string }>('app');
|
|
173
|
+
await app.listen(Number(process.env.PORT) || cfg?.port || 3000, cfg?.host || '0.0.0.0');
|
|
85
174
|
}
|
|
86
175
|
bootstrap();
|
|
87
176
|
```
|
|
88
177
|
|
|
89
|
-
|
|
178
|
+
**Pure microservice** (no HTTP server — `init()`, not `listen()`):
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { NestFactory } from '@nestjs/core';
|
|
182
|
+
import { AppModule } from './app.module';
|
|
183
|
+
|
|
184
|
+
async function bootstrap() {
|
|
185
|
+
const app = await NestFactory.create(AppModule);
|
|
186
|
+
app.enableShutdownHooks(); // drain in-flight RPC + close AMQP cleanly on SIGINT/SIGTERM
|
|
187
|
+
await app.init(); // @BrokerAction handlers start consuming once initialized
|
|
188
|
+
}
|
|
189
|
+
bootstrap();
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 4. `config/config.yaml` (starter)
|
|
90
193
|
|
|
91
194
|
```yaml
|
|
92
195
|
app:
|
|
@@ -94,28 +197,29 @@ app:
|
|
|
94
197
|
host: 0.0.0.0
|
|
95
198
|
environment: development
|
|
96
199
|
|
|
97
|
-
auth-providers: []
|
|
200
|
+
auth-providers: [] # gateway only — JWT/JWKS providers
|
|
98
201
|
|
|
99
202
|
broker:
|
|
203
|
+
name: rabbitmq
|
|
100
204
|
uri: "amqp://guest:guest@localhost:5672/"
|
|
101
|
-
defaultRpcTimeout: 10000
|
|
102
205
|
defaultSubscribeErrorBehavior: ack
|
|
206
|
+
defaultPublishErrorBehavior: reject
|
|
103
207
|
connectionManagerOptions:
|
|
104
208
|
heartbeatIntervalInSeconds: 60
|
|
105
209
|
reconnectTimeInSeconds: 60
|
|
106
210
|
connectionOptions:
|
|
107
211
|
clientProperties:
|
|
108
|
-
connection_name: my-service
|
|
212
|
+
connection_name: my-service # distinct per instance; needed for broadcast/WebSocket
|
|
109
213
|
credentials: { mechanism: PLAIN, username: guest, password: guest }
|
|
110
214
|
exchanges:
|
|
111
|
-
- name:
|
|
215
|
+
- name: rlb
|
|
112
216
|
type: direct
|
|
113
217
|
createExchangeIfNotExists: true
|
|
114
218
|
options: { durable: true }
|
|
115
219
|
queues:
|
|
116
220
|
- name: my-rpc-q
|
|
117
|
-
exchange:
|
|
118
|
-
routingKey: my
|
|
221
|
+
exchange: rlb
|
|
222
|
+
routingKey: my-rpc-q
|
|
119
223
|
createQueueIfNotExists: true
|
|
120
224
|
options: { durable: true }
|
|
121
225
|
|
|
@@ -123,38 +227,69 @@ topics:
|
|
|
123
227
|
- name: my-rpc
|
|
124
228
|
mode: rpc
|
|
125
229
|
queue: my-rpc-q
|
|
230
|
+
exchange: rlb
|
|
231
|
+
routingKey: my-rpc-q
|
|
126
232
|
|
|
233
|
+
# --- gateway only ---
|
|
127
234
|
gateway:
|
|
128
235
|
mode: gateway
|
|
236
|
+
events: []
|
|
129
237
|
paths:
|
|
130
|
-
- name:
|
|
238
|
+
- name: health
|
|
131
239
|
method: GET
|
|
132
|
-
path: /
|
|
240
|
+
path: /health
|
|
133
241
|
dataSource: query
|
|
134
|
-
topic:
|
|
135
|
-
action:
|
|
242
|
+
topic: rlb-gateway-admin # gateway-admin gw-health → 200 { status: 'ok' }
|
|
243
|
+
action: gw-health
|
|
136
244
|
mode: rpc
|
|
137
|
-
events: []
|
|
138
245
|
```
|
|
139
246
|
|
|
140
|
-
|
|
247
|
+
### Route auto-discovery (publisher side, optional)
|
|
248
|
+
|
|
249
|
+
A microservice can announce its `@BrokerHTTP` routes on boot. Add INSIDE the `broker`
|
|
250
|
+
block — `serviceName` is the ownership key AND fills `connection_name` when none is set
|
|
251
|
+
explicitly. `exchange`/`queue` default to `rlb-route-discovery` / `rlb-route-sync` and
|
|
252
|
+
must match the gateway's `GatewayAdminModule` `routeDiscovery { exchange, queue }`.
|
|
253
|
+
|
|
254
|
+
```yaml
|
|
255
|
+
broker:
|
|
256
|
+
# ...
|
|
257
|
+
routeDiscovery:
|
|
258
|
+
serviceName: my-service
|
|
259
|
+
publishOnBoot: true
|
|
260
|
+
# exchange: rlb-route-discovery # override to namespace per env (must match the gateway)
|
|
261
|
+
# queue: rlb-route-sync
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### 5. Sample handler (one method, both transports)
|
|
141
265
|
|
|
142
266
|
```ts
|
|
143
267
|
import { Injectable } from '@nestjs/common';
|
|
144
|
-
import { BrokerAction, BrokerParam } from '@open-rlb/nestjs-amqp';
|
|
268
|
+
import { BrokerAction, BrokerHTTP, BrokerParam } from '@open-rlb/nestjs-amqp';
|
|
145
269
|
|
|
146
270
|
@Injectable()
|
|
147
|
-
export class
|
|
148
|
-
@BrokerAction('my-rpc', 'ping',
|
|
149
|
-
|
|
150
|
-
|
|
271
|
+
export class AppService {
|
|
272
|
+
@BrokerAction('my-rpc', 'ping') // AMQP RPC on topic my-rpc, action ping
|
|
273
|
+
@BrokerHTTP('POST', '/ping', 'body') // route metadata for gateway auto-discovery
|
|
274
|
+
async ping(@BrokerParam('body', 'name') name: string) { // flat params, one decorator each
|
|
275
|
+
return { pong: true, name };
|
|
151
276
|
}
|
|
152
277
|
}
|
|
153
278
|
```
|
|
154
279
|
|
|
280
|
+
Add auth with `@BrokerAuth(authName, allowAnonymous?, roles?, httpName?)` — decoupled from
|
|
281
|
+
`@BrokerHTTP`. With one `@BrokerHTTP` it auto-pairs (no `httpName` needed); with multiple,
|
|
282
|
+
each `@BrokerHTTP` sets a `name` and each `@BrokerAuth` targets it via `httpName`. A route
|
|
283
|
+
with no `@BrokerAuth` is public.
|
|
284
|
+
|
|
155
285
|
## Verify
|
|
156
|
-
- topic/queue/exchange names line up (gotchas 5–7);
|
|
157
|
-
|
|
286
|
+
- topic/queue/exchange names line up across `broker`/`topics`/paths (gotchas 5–7);
|
|
287
|
+
`connection_name` set if using broadcast/WebSocket (8).
|
|
288
|
+
- Route-discovery `exchange`/`queue` identical on publisher and gateway.
|
|
289
|
+
- Reload DB routes at runtime via the `gw-reload` action on the broadcast control topic
|
|
290
|
+
(default `rlb-gateway-control`).
|
|
291
|
+
- `npm run build`, start with a reachable RabbitMQ, hit `/health` (gateway) or publish to
|
|
292
|
+
the RPC topic (microservice).
|
|
158
293
|
|
|
159
|
-
After scaffolding, use `rlb-amqp-add-action` / `rlb-amqp-add-route` /
|
|
160
|
-
to grow the service.
|
|
294
|
+
After scaffolding, use `rlb-amqp-add-action` / `rlb-amqp-add-route` /
|
|
295
|
+
`rlb-amqp-add-ws-event` to grow the service.
|