Skip to content

Commit b69ae0f

Browse files
feat: expose prettyPrint method param (fastify#4623)
1 parent 9e92e4f commit b69ae0f

File tree

4 files changed

+198
-33
lines changed

4 files changed

+198
-33
lines changed

docs/Reference/Server.md

Lines changed: 83 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1545,35 +1545,61 @@ a custom constraint strategy with the same name.
15451545
#### printRoutes
15461546
<a id="print-routes"></a>
15471547
1548-
`fastify.printRoutes()`: Prints the representation of the internal radix tree
1549-
used by the router, useful for debugging. Alternatively, `fastify.printRoutes({
1550-
commonPrefix: false })` can be used to print the flattened routes tree.
1548+
`fastify.printRoutes()`: Fastify router builds a tree of routes for each HTTP
1549+
method. If you call the prettyPrint without specifying an HTTP method, it will
1550+
merge all the trees into one and print it. The merged tree doesn't represent the
1551+
internal router structure. **Don't use it for debugging.**
15511552
15521553
*Remember to call it inside or after a `ready` call.*
15531554
15541555
```js
15551556
fastify.get('/test', () => {})
15561557
fastify.get('/test/hello', () => {})
1557-
fastify.get('/hello/world', () => {})
1558-
fastify.get('/helicopter', () => {})
1558+
fastify.get('/testing', () => {})
1559+
fastify.get('/testing/:param', () => {})
1560+
fastify.put('/update', () => {})
15591561

15601562
fastify.ready(() => {
15611563
console.log(fastify.printRoutes())
15621564
// └── /
15631565
// ├── test (GET)
1564-
// │ └── /hello (GET)
1565-
// └── hel
1566-
// ├── lo/world (GET)
1567-
// └── licopter (GET)
1566+
// │ ├── /hello (GET)
1567+
// │ └── ing (GET)
1568+
// │ └── /
1569+
// │ └── :param (GET)
1570+
// └── update (PUT)
1571+
})
1572+
```
15681573
1569-
console.log(fastify.printRoutes({ commonPrefix: false }))
1570-
// └── / (-)
1571-
// ├── test (GET)
1572-
// │ └── /hello (GET)
1573-
// ├── hello/world (GET)
1574-
// └── helicopter (GET)
1574+
If you want to print the internal router tree, you should specify the `method`
1575+
param. Printed tree will represent the internal router structure.
1576+
**You can use it for debugging.**
15751577
1576-
})
1578+
```js
1579+
console.log(fastify.printRoutes({ method: 'GET' }))
1580+
// └── /
1581+
// └── test (GET)
1582+
// ├── /hello (GET)
1583+
// └── ing (GET)
1584+
// └── /
1585+
// └── :param (GET)
1586+
1587+
console.log(fastify.printRoutes({ method: 'PUT' }))
1588+
// └── /
1589+
// └── update (PUT)
1590+
```
1591+
1592+
`fastify.printRoutes({ commonPrefix: false })` will print compressed trees. This
1593+
might useful when you have a large number of routes with common prefixes.
1594+
It doesn't represent the internal router structure. **Don't use it for debugging.**
1595+
1596+
```js
1597+
console.log(fastify.printRoutes({ commonPrefix: false }))
1598+
// ├── /test (GET)
1599+
// │ ├── /hello (GET)
1600+
// │ └── ing (GET)
1601+
// │ └── /:param (GET)
1602+
// └── /update (PUT)
15771603
```
15781604
15791605
`fastify.printRoutes({ includeMeta: (true | []) })` will display properties from
@@ -1583,26 +1609,51 @@ A shorthand option, `fastify.printRoutes({ includeHooks: true })` will include
15831609
all [hooks](./Hooks.md).
15841610
15851611
```js
1586-
console.log(fastify.printRoutes({ includeHooks: true, includeMeta: ['metaProperty'] }))
1612+
fastify.get('/test', () => {})
1613+
fastify.get('/test/hello', () => {})
1614+
1615+
const onTimeout = () => {}
1616+
1617+
fastify.addHook('onRequest', () => {})
1618+
fastify.addHook('onTimeout', onTimeout)
1619+
1620+
console.log(fastify.printRoutes({ includeHooks: true, includeMeta: ['errorHandler'] }))
15871621
// └── /
1588-
// ├── test (GET)
1589-
// │ • (onRequest) ["anonymous()","namedFunction()"]
1590-
// │ • (metaProperty) "value"
1591-
// │ └── /hello (GET)
1592-
// └── hel
1593-
// ├── lo/world (GET)
1594-
// │ • (onTimeout) ["anonymous()"]
1595-
// └── licopter (GET)
1622+
// └── test (GET)
1623+
// • (onTimeout) ["onTimeout()"]
1624+
// • (onRequest) ["anonymous()"]
1625+
// • (errorHandler) "defaultErrorHandler()"
1626+
// test (HEAD)
1627+
// • (onTimeout) ["onTimeout()"]
1628+
// • (onRequest) ["anonymous()"]
1629+
// • (onSend) ["headRouteOnSendHandler()"]
1630+
// • (errorHandler) "defaultErrorHandler()"
1631+
// └── /hello (GET)
1632+
// • (onTimeout) ["onTimeout()"]
1633+
// • (onRequest) ["anonymous()"]
1634+
// • (errorHandler) "defaultErrorHandler()"
1635+
// /hello (HEAD)
1636+
// • (onTimeout) ["onTimeout()"]
1637+
// • (onRequest) ["anonymous()"]
1638+
// • (onSend) ["headRouteOnSendHandler()"]
1639+
// • (errorHandler) "defaultErrorHandler()"
15961640

15971641
console.log(fastify.printRoutes({ includeHooks: true }))
15981642
// └── /
1599-
// ├── test (GET)
1600-
// │ • (onRequest) ["anonymous()","namedFunction()"]
1601-
// │ └── /hello (GET)
1602-
// └── hel
1603-
// ├── lo/world (GET)
1604-
// │ • (onTimeout) ["anonymous()"]
1605-
// └── licopter (GET)
1643+
// └── test (GET)
1644+
// • (onTimeout) ["onTimeout()"]
1645+
// • (onRequest) ["anonymous()"]
1646+
// test (HEAD)
1647+
// • (onTimeout) ["onTimeout()"]
1648+
// • (onRequest) ["anonymous()"]
1649+
// • (onSend) ["headRouteOnSendHandler()"]
1650+
// └── /hello (GET)
1651+
// • (onTimeout) ["onTimeout()"]
1652+
// • (onRequest) ["anonymous()"]
1653+
// /hello (HEAD)
1654+
// • (onTimeout) ["onTimeout()"]
1655+
// • (onRequest) ["anonymous()"]
1656+
// • (onSend) ["headRouteOnSendHandler()"]
16061657
```
16071658
16081659
#### printPlugins

test/pretty-print.test.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,41 @@ test('pretty print - static routes', t => {
2727
})
2828
})
2929

30+
test('pretty print - internal tree - static routes', t => {
31+
t.plan(4)
32+
33+
const fastify = Fastify({ exposeHeadRoutes: false })
34+
fastify.get('/test', () => {})
35+
fastify.get('/test/hello', () => {})
36+
fastify.get('/hello/world', () => {})
37+
38+
fastify.put('/test', () => {})
39+
fastify.put('/test/foo', () => {})
40+
41+
fastify.ready(() => {
42+
const getTree = fastify.printRoutes({ method: 'GET' })
43+
const expectedGetTree = `\
44+
└── /
45+
├── test (GET)
46+
│ └── /hello (GET)
47+
└── hello/world (GET)
48+
`
49+
50+
t.equal(typeof getTree, 'string')
51+
t.equal(getTree, expectedGetTree)
52+
53+
const putTree = fastify.printRoutes({ method: 'PUT' })
54+
const expectedPutTree = `\
55+
└── /
56+
└── test (PUT)
57+
└── /foo (PUT)
58+
`
59+
60+
t.equal(typeof putTree, 'string')
61+
t.equal(putTree, expectedPutTree)
62+
})
63+
})
64+
3065
test('pretty print - parametric routes', t => {
3166
t.plan(2)
3267

@@ -52,6 +87,44 @@ test('pretty print - parametric routes', t => {
5287
})
5388
})
5489

90+
test('pretty print - internal tree - parametric routes', t => {
91+
t.plan(4)
92+
93+
const fastify = Fastify({ exposeHeadRoutes: false })
94+
fastify.get('/test', () => {})
95+
fastify.get('/test/:hello', () => {})
96+
fastify.get('/hello/:world', () => {})
97+
98+
fastify.put('/test', () => {})
99+
fastify.put('/test/:hello', () => {})
100+
101+
fastify.ready(() => {
102+
const getTree = fastify.printRoutes({ method: 'GET' })
103+
const expectedGetTree = `\
104+
└── /
105+
├── test (GET)
106+
│ └── /
107+
│ └── :hello (GET)
108+
└── hello/
109+
└── :world (GET)
110+
`
111+
112+
t.equal(typeof getTree, 'string')
113+
t.equal(getTree, expectedGetTree)
114+
115+
const putTree = fastify.printRoutes({ method: 'PUT' })
116+
const expectedPutTree = `\
117+
└── /
118+
└── test (PUT)
119+
└── /
120+
└── :hello (PUT)
121+
`
122+
123+
t.equal(typeof putTree, 'string')
124+
t.equal(putTree, expectedPutTree)
125+
})
126+
})
127+
55128
test('pretty print - mixed parametric routes', t => {
56129
t.plan(2)
57130

@@ -102,6 +175,44 @@ test('pretty print - wildcard routes', t => {
102175
})
103176
})
104177

178+
test('pretty print - internal tree - wildcard routes', t => {
179+
t.plan(4)
180+
181+
const fastify = Fastify({ exposeHeadRoutes: false })
182+
fastify.get('/test', () => {})
183+
fastify.get('/test/*', () => {})
184+
fastify.get('/hello/*', () => {})
185+
186+
fastify.put('/*', () => {})
187+
fastify.put('/test/*', () => {})
188+
189+
fastify.ready(() => {
190+
const getTree = fastify.printRoutes({ method: 'GET' })
191+
const expectedGetTree = `\
192+
└── /
193+
├── test (GET)
194+
│ └── /
195+
│ └── * (GET)
196+
└── hello/
197+
└── * (GET)
198+
`
199+
200+
t.equal(typeof getTree, 'string')
201+
t.equal(getTree, expectedGetTree)
202+
203+
const putTree = fastify.printRoutes({ method: 'PUT' })
204+
const expectedPutTree = `\
205+
└── /
206+
├── test/
207+
│ └── * (PUT)
208+
└── * (PUT)
209+
`
210+
211+
t.equal(typeof putTree, 'string')
212+
t.equal(putTree, expectedPutTree)
213+
})
214+
})
215+
105216
test('pretty print - empty plugins', t => {
106217
t.plan(2)
107218

test/types/instance.test-d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,8 @@ expectType<string>(server.printRoutes({ includeHooks: true, commonPrefix: false,
284284

285285
expectType<string>(server.printRoutes({ includeMeta: ['key1', Symbol('key2')] }))
286286

287+
expectType<string>(server.printRoutes({ method: 'GET' }))
288+
287289
expectType<string>(server.printRoutes())
288290

289291
server.decorate<(x: string) => void>('test', function (x: string): void {

types/instance.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ import {
2020
FastifyTypeProvider,
2121
FastifyTypeProviderDefault
2222
} from './type-provider'
23-
import { ContextConfigDefault, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault } from './utils'
23+
import { HTTPMethods, ContextConfigDefault, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault } from './utils'
2424
import { AddressInfo } from 'net'
2525

2626
export interface PrintRoutesOptions {
27+
method?: HTTPMethods;
2728
includeMeta?: boolean | (string | symbol)[]
2829
commonPrefix?: boolean
2930
includeHooks?: boolean

0 commit comments

Comments
 (0)