You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/connect/client.mdx
+125Lines changed: 125 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -181,6 +181,131 @@ func main() {
181
181
}
182
182
```
183
183
184
+
## Directory Structure & Organization
185
+
186
+
The Cosmo Router uses a convention-based directory structure to automatically discover and load Connect RPC services. This approach co-locates proto files with their GraphQL operations for easy management.
187
+
188
+
### Configuration
189
+
190
+
Configure the router to point to your root services directory using a storage provider:
191
+
192
+
```yaml config.yaml
193
+
connect_rpc:
194
+
enabled: true
195
+
server:
196
+
listen_addr: "0.0.0.0:8081"
197
+
services_provider_id: "fs-services"
198
+
199
+
storage_providers:
200
+
file_system:
201
+
- id: "fs-services"
202
+
path: "./services" # Root services directory
203
+
```
204
+
205
+
The router will recursively walk the `services` directory and automatically discover all proto files and their associated GraphQL operations.
206
+
207
+
### Recommended Structure
208
+
209
+
For organization purposes, we recommend keeping all services in a root `services` directory, with subdirectories for packages and individual services.
210
+
211
+
#### Single Service per Package
212
+
213
+
When you have one service per package, you can organize files directly in the package directory:
214
+
215
+
```
216
+
services/
217
+
└── employee.v1/ # Package directory
218
+
├── employee.proto # Proto definition
219
+
├── employee.proto.lock.json
220
+
├── GetEmployee.graphql # Operation files
221
+
├── UpdateEmployee.graphql
222
+
└── DeleteEmployee.graphql
223
+
```
224
+
225
+
Or with operations in a subdirectory:
226
+
227
+
```
228
+
services/
229
+
└── employee.v1/
230
+
├── employee.proto
231
+
├── employee.proto.lock.json
232
+
└── operations/
233
+
├── GetEmployee.graphql
234
+
├── UpdateEmployee.graphql
235
+
└── DeleteEmployee.graphql
236
+
```
237
+
238
+
#### Multiple Services per Package
239
+
240
+
When multiple services share the same proto package, organize them in service subdirectories:
241
+
242
+
```
243
+
services/
244
+
└── company.v1/ # Package directory
245
+
├── EmployeeService/ # First service
246
+
│ ├── employee.proto # package company.v1; service EmployeeService
247
+
│ ├── employee.proto.lock.json
248
+
│ └── operations/
249
+
│ ├── GetEmployee.graphql
250
+
│ └── UpdateEmployee.graphql
251
+
└── DepartmentService/ # Second service, same package
252
+
├── department.proto # package company.v1; service DepartmentService
253
+
├── department.proto.lock.json
254
+
└── operations/
255
+
├── GetDepartment.graphql
256
+
└── ListDepartments.graphql
257
+
```
258
+
259
+
### Flexible Organization
260
+
261
+
The router determines service identity by proto package declarations, not directory names. This gives you flexibility in organizing your files:
262
+
263
+
```
264
+
services/
265
+
├── hr-services/
266
+
│ ├── employee.proto # package company.v1; service EmployeeService
267
+
│ └── GetEmployee.graphql
268
+
└── admin-services/
269
+
├── department.proto # package company.v1; service DepartmentService
270
+
└── GetDepartment.graphql
271
+
```
272
+
273
+
<Note>
274
+
**Service Uniqueness**: The combination of proto package name and service name must be unique. For example, you can have multiple services with the same package name (e.g., `company.v1`) as long as they have different service names (`EmployeeService`, `DepartmentService`). The router uses the package + service combination to identify and route requests.
275
+
</Note>
276
+
277
+
### Discovery Rules
278
+
279
+
The router follows these rules when discovering services:
280
+
281
+
1. **Recursive Discovery**: The router recursively walks the services directory to find all `.proto` files
282
+
2. **Proto Association**: Each `.proto` file discovered becomes a service endpoint
283
+
3. **Operation Association**: All `.graphql` files in the same directory (or subdirectories) are associated with the nearest parent `.proto` file
284
+
4. **Nested Proto Limitation**: If a `.proto` file is found in a directory, any `.proto` files in subdirectories are **not** discovered (the parent proto takes precedence)
285
+
286
+
#### Example: Nested Proto Files
287
+
288
+
```
289
+
services/
290
+
└── employee.v1/
291
+
├── employee.proto # ✅ Discovered as a service
292
+
├── GetEmployee.graphql # ✅ Associated with employee.proto
293
+
└── nested/
294
+
├── other.proto # ❌ NOT discovered (parent proto found first)
295
+
└── UpdateEmployee.graphql # ✅ Still associated with employee.proto
296
+
```
297
+
298
+
<Warning>
299
+
**Avoid Nested Proto Files**: Do not place `.proto` files in subdirectories of a directory that already contains a `.proto` file. The nested proto files will not be discovered by the router.
300
+
</Warning>
301
+
302
+
### Best Practices
303
+
304
+
1. **Use Semantic Versioning**: Include version numbers in package names (e.g., `employee.v1`, `employee.v2`) to support API evolution
305
+
2. **Co-locate Operations**: Keep GraphQL operations close to their proto definitions for easier maintenance
306
+
3. **Consistent Naming**: Use clear, descriptive names for packages and services that reflect their purpose
307
+
4. **Lock File Management**: Always commit `.proto.lock.json` files to version control to maintain field number stability
308
+
184
309
## Observability
185
310
186
311
The Cosmo Router provides built-in [observability features](/router/metrics-and-monitoring) that work seamlessly with Connect Client. Because the Router translates RPC calls into GraphQL operations, you get detailed metrics and tracing for both layers.
0 commit comments