A VS Code extension that takes a backend endpoint URL and jumps you to the NestJS controller and exact handler method that serves it — useful in large codebases and monorepos where routes are assembled from several layers.
http://localhost:3000/users/list?search=
→ ListUsersController.listUsers
src/users/web/list-users.controller.ts:34
What it understands
A full route is composed of up to three layers, and the extension resolves all of them statically (via the TypeScript AST — no running server required):
| Layer | Source | Example |
|---|---|---|
| RouterModule prefix | RouterModule.register([{ path, module }]) |
billing/invoices |
| Controller prefix | @Controller("...") |
orders |
| Method path | @Get/@Post/@Put/@Patch/@Delete("...") |
/:orderId/items |
So GET /billing/invoices/orders/abc/items is traced to the right handler,
capturing orderId = abc.
It correctly handles:
- Module prefixes via
RouterModule(including nestedchildren). - Prefix routes and paths combined from different fragments (module + controller + method), with slashes normalised.
- Path params —
:idin decorators and[id]folder segments are matched against any value, and the captured values are shown. - Same-named modules in different files — modules and controllers are disambiguated by their resolved import file path, not by class name, so a controller never inherits a prefix from an unrelated module that happens to share a name.
- Multi-path decorators (
@Get(["a", "b"])) and@Controller({ path })form. - Query strings, hosts and verbs in the input are stripped/parsed:
GET http://localhost:3000/foo?x=1→ verbGET, path/foo.
Usage
Open your NestJS project as the workspace, then either:
- Click the Endpoint Tracer icon in the activity bar, paste an endpoint, and
press Trace endpoint (or
Enter). Click any result to open it at the handler line. - Run
Endpoint Tracer: Find Controller for Endpointfrom the command palette for a quick-pick flow.
If no route matches exactly, the closest partial matches (by leading path segments) are shown instead.
Configuration
| Setting | Default | Description |
|---|---|---|
endpointTracer.sourceRoots |
["src", "apps/*/src", "libs/*/src", "packages/*/src"] |
Folders scanned for *.controller.ts / *.module.ts, relative to each workspace folder. A trailing * segment is expanded one level. The first existing root wins; the rest are fallbacks. Add your own layout here if it differs. |
endpointTracer.maxResults |
30 |
Max matches shown. |
The index builds on activation and rebuilds automatically when any
*.controller.ts / *.module.ts changes. Use Endpoint Tracer: Rebuild Route Index to force a refresh.
Develop
npm install
npm run compile # or: npm run watch
Press F5 to launch an Extension Development Host. The bundled Run Extension
launch config opens a sibling ../backend folder as the test workspace — edit
.vscode/launch.json to point it at any NestJS project you want to trace.
How it works
- Index — every
*.controller.tsis parsed for its@Controllerpath(s) and HTTP-method decorators; every*.module.tsis parsed for itscontrollers: [...]membership (expanding...spreadof localconstarrays) and anyRouterModule.registerprefixes. Imports are resolved to absolute file paths so identically-named classes stay distinct. - Resolve — prefixes flow module → controller (by file path), and each handler becomes one or more fully-qualified routes.
- Match — the queried URL is normalised to segments and matched against the
route table segment-by-segment, with
:paramsegments acting as wildcards and exact (literal) matches ranked above param-heavy ones.
Limitations
Matching is purely static path matching. It does not evaluate guards, a global
prefix set via app.setGlobalPrefix(...), controller-level API versioning
(@Controller({ version })), or routes registered dynamically at runtime.
License
MIT