{"id":20029178,"url":"https://github.com/jsonjoy-com/jit-router","last_synced_at":"2025-08-30T23:39:27.750Z","repository":{"id":234693262,"uuid":"789395120","full_name":"jsonjoy-com/jit-router","owner":"jsonjoy-com","description":"High-performance JIT router for Node.js","archived":false,"fork":false,"pushed_at":"2025-07-29T08:49:27.000Z","size":172,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-08T18:30:00.079Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsonjoy-com.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"streamich"}},"created_at":"2024-04-20T12:29:54.000Z","updated_at":"2025-07-29T08:48:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"ceef8cac-1fa1-4345-b526-a2be4120225c","html_url":"https://github.com/jsonjoy-com/jit-router","commit_stats":null,"previous_names":["jsonjoy-com/jit-router"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/jsonjoy-com/jit-router","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonjoy-com%2Fjit-router","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonjoy-com%2Fjit-router/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonjoy-com%2Fjit-router/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonjoy-com%2Fjit-router/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsonjoy-com","download_url":"https://codeload.github.com/jsonjoy-com/jit-router/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsonjoy-com%2Fjit-router/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272921574,"owners_count":25015761,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T09:18:47.256Z","updated_at":"2025-08-30T23:39:27.744Z","avatar_url":"https://github.com/jsonjoy-com.png","language":"TypeScript","funding_links":["https://github.com/sponsors/streamich"],"categories":[],"sub_categories":[],"readme":"# `json-joy` JIT Router\n\nA high-performance HTTP router that constructs a hybrid Trie and Radix tree of the route structure and then JIT compiles the routes into a single optimized function for maximum performance.\n\n## Key Features\n\n- **Ultra-Fast Performance**: JIT compilation generates optimized JavaScript functions for route matching\n- **Hybrid Tree Structure**: Combines Trie and Radix tree algorithms for efficient path matching\n- **Flexible Route Patterns**: Supports exact matches, parameters, wildcards, and regex patterns\n- **Parameter Extraction**: Automatically extracts and validates route parameters\n- **TypeScript Support**: Full TypeScript definitions with generic data types\n- **Zero Dependencies**: Core runtime has no external dependencies for maximum efficiency\n\n## Installation\n\n```bash\nnpm install @jsonjoy.com/jit-router\n```\n\n## Quick Start\n\n```typescript\nimport { Router } from '@jsonjoy.com/jit-router';\n\n// Create a new router instance\nconst router = new Router();\n\n// Add routes with associated data\nrouter.add('GET /users', { handler: 'listUsers' });\nrouter.add('GET /users/{id}', { handler: 'getUser' });\nrouter.add('POST /users/{id}/posts', { handler: 'createPost' });\n\n// Compile routes into an optimized matcher function\nconst matcher = router.compile();\n\n// Match incoming requests\nconst match = matcher('GET /users/123');\nif (match) {\n  console.log(match.data);    // { handler: 'getUser' }\n  console.log(match.params);  // ['123']\n}\n```\n\n## Destinations\n\nDestinations are the core concept in jit-router. Each destination represents an endpoint with associated data and can be reached via one or more route patterns.\n\n### Creating Destinations\n\n```typescript\n// Single route destination\nrouter.add('GET /ping', 'PING_HANDLER');\n\n// Multiple routes leading to same destination\nrouter.add(['GET /ping', 'GET /pong'], 'PING_HANDLER');\n\n// With custom data\nrouter.add('GET /users/{id}', { \n  handler: getUserHandler,\n  middleware: [authMiddleware],\n  cache: true \n});\n```\n\n### Destination Properties\n\nEach destination contains:\n- **routes**: Array of route patterns that lead to this destination\n- **data**: Associated data (handler, metadata, etc.)\n- **match**: Match object returned when route is matched\n\n## Route Patterns and Step Specifications\n\nRoutes consist of steps that define the matching pattern. There are three types of steps:\n\n### 1. Exact Steps\n\nMatch literal text exactly:\n\n```typescript\nrouter.add('GET /api/users', 'USERS_API');\nrouter.add('POST /login', 'LOGIN');\n```\n\n### 2. Parameter Steps (Until Steps)\n\nExtract parameters from the URL path:\n\n```typescript\n// Basic parameter - matches until next '/'\nrouter.add('GET /users/{id}', 'GET_USER');\n\n// Custom delimiter - matches until specified character\nrouter.add('GET /files/{name}.{ext}', 'GET_FILE');\n\n// Wildcard - matches until end of string\nrouter.add('GET /static/{path::\\n}', 'STATIC_FILES');\n```\n\n#### Parameter Syntax:\n- `{name}` - matches until next `/` (default delimiter)\n- `{name::delimiter}` - matches until specified delimiter\n- `{name::\\n}` - matches until end of string (wildcard)\n\n### 3. Regex Steps\n\nMatch parameters with regex patterns:\n\n```typescript\n// HTTP method matching\nrouter.add('{method:(GET|POST)} /api/{endpoint}', 'API_HANDLER');\n\n// Numeric IDs only\nrouter.add('GET /users/{id:[0-9]+}', 'GET_USER_BY_ID');\n\n// Optional path segments\nrouter.add('GET /posts{slug:(/[^/]+)?}', 'GET_POST');\n\n// Complex patterns\nrouter.add('{method:[A-Z]+} /rpc/{procedure}', 'RPC_HANDLER');\n```\n\n#### Regex Syntax:\n- `{name:pattern}` - matches with regex pattern\n- `{name:pattern:delimiter}` - regex pattern with custom delimiter\n\n## Parameter Extraction\n\nParameters are automatically extracted and provided in the match result:\n\n```typescript\nconst router = new Router();\nrouter.add('GET /users/{userId}/posts/{postId}', 'GET_USER_POST');\nconst matcher = router.compile();\n\nconst match = matcher('GET /users/123/posts/456');\n// match.params = ['123', '456']\n\n// Parameters correspond to the order they appear in the route\nconst [userId, postId] = match.params;\n```\n\n### Named Parameter Access\n\nFor better parameter handling, consider structuring your data to include parameter names:\n\n```typescript\nrouter.add('GET /users/{userId}/posts/{postId}', {\n  handler: 'getUserPost',\n  params: ['userId', 'postId']\n});\n\nconst match = matcher('GET /users/123/posts/456');\nif (match) {\n  const params = {};\n  match.data.params.forEach((name, index) =\u003e {\n    params[name] = match.params[index];\n  });\n  // params = { userId: '123', postId: '456' }\n}\n```\n\n## Code Generation and Compilation\n\nThe router uses JIT (Just-In-Time) compilation to generate highly optimized JavaScript functions:\n\n### Compilation Process\n\n1. **Tree Construction**: Routes are organized into a hybrid Trie/Radix tree structure\n2. **Code Generation**: The tree is traversed to generate optimized JavaScript code\n3. **Function Creation**: Code is compiled into a fast matcher function\n\n```typescript\nconst router = new Router();\nrouter.add('GET /users/{id}', 'USER_HANDLER');\n\n// View the internal tree structure\nconsole.log(router.toString());\n\n// Compile to optimized function\nconst matcher = router.compile();\n\n// View generated code (for debugging)\nconsole.log(matcher.toString());\n```\n\n### Performance Characteristics\n\nThe JIT compilation produces functions with these optimizations:\n- **No loops**: Uses conditional branches instead of iteration\n- **String operations**: Optimized string slicing and comparison\n- **Early returns**: Matches return immediately when found\n- **Minimal allocations**: Reuses objects and avoids unnecessary memory allocation\n\n## Advanced Usage Examples\n\n### Complex Routing Patterns\n\n```typescript\nconst router = new Router();\n\n// API versioning\nrouter.add('GET /api/v{version:[12]}/users', 'API_USERS');\n\n// File serving with extensions\nrouter.add('GET /assets/{file}.{ext:(js|css|png|jpg)}', 'STATIC_ASSET');\n\n// Optional trailing slashes\nrouter.add('GET /blog{trailing:/?}', 'BLOG_INDEX');\n\n// Nested parameters with validation\nrouter.add('POST /orgs/{org}/repos/{repo}/issues/{num:[0-9]+}', 'GITHUB_ISSUE');\n\n// Wildcard with method matching\nrouter.add('{method:(GET|HEAD)} /files/{path::\\n}', 'FILE_HANDLER');\n\nconst matcher = router.compile();\n```\n\n### Custom Router Options\n\n```typescript\n// Custom default delimiter\nconst router = new Router({ \n  defaultUntil: '|'  // Use '|' instead of '/' as default delimiter\n});\n\nrouter.add('GET |users|{id}', 'USER_HANDLER');\n```\n\n### Type-Safe Usage with TypeScript\n\n```typescript\ninterface RouteData {\n  handler: string;\n  middleware?: Function[];\n  cache?: boolean;\n}\n\nconst router = new Router\u003cRouteData\u003e();\n\nrouter.add('GET /users/{id}', {\n  handler: 'getUser',\n  middleware: [authMiddleware],\n  cache: true\n});\n\nconst matcher = router.compile();\nconst match = matcher('GET /users/123');\n\nif (match) {\n  // TypeScript knows match.data is RouteData\n  console.log(match.data.handler);     // 'getUser'\n  console.log(match.data.cache);       // true\n  console.log(match.params);           // ['123']\n}\n```\n\n### Route Introspection\n\n```typescript\nconst router = new Router();\nrouter.add('GET /users/{id}', 'USER_HANDLER');\nrouter.add('POST /users', 'CREATE_USER');\n\n// Inspect destinations\nconsole.log('Destinations:', router.destinations.length);\nrouter.destinations.forEach((dest, i) =\u003e {\n  console.log(`[${i}]:`, dest.routes.map(r =\u003e r.toText()));\n});\n\n// View routing tree structure\nconst tree = router.tree();\nconsole.log(tree.toString('  '));\n```\n\n## API Reference\n\n### Router Class\n\n#### Constructor\n```typescript\nnew Router\u003cData\u003e(options?: RouterOptions)\n```\n\n**Options:**\n- `defaultUntil?: string` - Default delimiter for parameter steps (default: '/')\n\n#### Methods\n\n##### `add(route: string | string[], data: Data): void`\nAdd a route or multiple routes to the same destination.\n\n##### `addDestination(destination: Destination): void`\nAdd a pre-constructed destination.\n\n##### `compile(): RouteMatcher\u003cData\u003e`\nCompile routes into an optimized matcher function.\n\n##### `tree(): RoutingTreeNode`\nGet the internal routing tree structure.\n\n### RouteMatcher Function\n\n```typescript\n(route: string) =\u003e Match\u003cData\u003e | undefined\n```\n\nReturns a `Match` object if the route matches, `undefined` otherwise.\n\n### Match Object\n\n```typescript\ninterface Match\u003cData\u003e {\n  data: Data;           // Associated route data\n  params: string[];     // Extracted parameters\n}\n```\n\n### Route Step Types\n\n#### ExactStep\nMatches literal text exactly.\n\n#### UntilStep  \nMatches parameters until a delimiter:\n- `name: string` - Parameter name\n- `until: string` - Delimiter character\n\n#### RegexStep\nMatches parameters with regex patterns:\n- `name: string` - Parameter name  \n- `regex: string` - Regex pattern\n- `until: string` - Delimiter character\n\n## Error Handling\n\nThe router handles various edge cases gracefully:\n\n```typescript\nconst router = new Router();\nrouter.add('GET /users/{id}', 'USER_HANDLER');\nconst matcher = router.compile();\n\n// Non-matching routes return undefined\nconsole.log(matcher('GET /posts/123'));     // undefined\nconsole.log(matcher('POST /users/123'));    // undefined\n\n// Empty or invalid routes return undefined  \nconsole.log(matcher(''));                   // undefined\nconsole.log(matcher('INVALID'));           // undefined\n```\n\n\n## Benchmarks\n\nComparing `json-joy` against the second fastest router `find-my-way` (used in Fastify):\n\n```\nnpx ts-node src/__bench__/realistic.bench.ts\n```\n\nResults:\n\n```\njson-joy router x 1,799,920 ops/sec ±0.74% (99 runs sampled), 556 ns/op\nfind-my-way x 389,132 ops/sec ±4.60% (87 runs sampled), 2570 ns/op\njson-joy router: GET /ping x 151,628,101 ops/sec ±1.83% (87 runs sampled), 7 ns/op\nfind-my-way: GET /ping x 14,820,512 ops/sec ±0.23% (100 runs sampled), 67 ns/op\njson-joy router: GET /pong x 103,442,010 ops/sec ±0.49% (101 runs sampled), 10 ns/op\nfind-my-way: GET /pong x 12,396,065 ops/sec ±0.14% (95 runs sampled), 81 ns/op\njson-joy router: POST /ping x 155,689,270 ops/sec ±0.26% (96 runs sampled), 6 ns/op\nfind-my-way: POST /ping x 14,964,742 ops/sec ±0.62% (100 runs sampled), 67 ns/op\njson-joy router: POST /echo x 103,757,580 ops/sec ±0.24% (94 runs sampled), 10 ns/op\nfind-my-way: POST /echo x 19,484,996 ops/sec ±0.13% (100 runs sampled), 51 ns/op\njson-joy router: GET /info x 86,407,568 ops/sec ±0.45% (101 runs sampled), 12 ns/op\nfind-my-way: GET /info x 19,090,564 ops/sec ±0.23% (99 runs sampled), 52 ns/op\njson-joy router: GET /types x 82,040,568 ops/sec ±0.19% (93 runs sampled), 12 ns/op\nfind-my-way: GET /types x 18,258,167 ops/sec ±0.13% (94 runs sampled), 55 ns/op\njson-joy router: PUT /events x 155,566,843 ops/sec ±0.30% (95 runs sampled), 6 ns/op\nfind-my-way: PUT /events x 17,947,965 ops/sec ±0.29% (95 runs sampled), 56 ns/op\njson-joy router: GET /users x 67,873,498 ops/sec ±0.19% (97 runs sampled), 15 ns/op\nfind-my-way: GET /users x 18,427,182 ops/sec ±0.70% (97 runs sampled), 54 ns/op\njson-joy router: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 24,268,077 ops/sec ±0.38% (98 runs sampled), 41 ns/op\nfind-my-way: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 5,830,219 ops/sec ±0.20% (101 runs sampled), 172 ns/op\njson-joy router: GET /users/123 x 23,750,636 ops/sec ±0.92% (98 runs sampled), 42 ns/op\nfind-my-way: GET /users/123 x 8,883,381 ops/sec ±0.15% (98 runs sampled), 113 ns/op\njson-joy router: DELETE /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 21,578,200 ops/sec ±0.98% (96 runs sampled), 46 ns/op\nfind-my-way: DELETE /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 6,081,393 ops/sec ±0.82% (96 runs sampled), 164 ns/op\njson-joy router: POST /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 19,981,015 ops/sec ±0.16% (96 runs sampled), 50 ns/op\nfind-my-way: POST /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx x 6,094,531 ops/sec ±0.27% (96 runs sampled), 164 ns/op\njson-joy router: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers x 17,566,830 ops/sec ±0.92% (99 runs sampled), 57 ns/op\nfind-my-way: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers x 4,584,840 ops/sec ±0.27% (97 runs sampled), 218 ns/op\njson-joy router: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 13,432,092 ops/sec ±0.26% (100 runs sampled), 74 ns/op\nfind-my-way: GET /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 2,959,002 ops/sec ±0.17% (100 runs sampled), 338 ns/op\njson-joy router: POST /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 12,074,790 ops/sec ±1.05% (98 runs sampled), 83 ns/op\nfind-my-way: POST /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 3,211,678 ops/sec ±0.31% (96 runs sampled), 311 ns/op\njson-joy router: DELETE /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 12,878,647 ops/sec ±0.30% (99 runs sampled), 78 ns/op\nfind-my-way: DELETE /users/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/followers/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy x 3,214,022 ops/sec ±0.69% (95 runs sampled), 311 ns/op\njson-joy router: GET /posts x 47,369,117 ops/sec ±1.64% (83 runs sampled), 21 ns/op\nfind-my-way: GET /posts x 11,424,540 ops/sec ±0.17% (101 runs sampled), 88 ns/op\njson-joy router: GET /posts/search x 91,571,586 ops/sec ±1.22% (94 runs sampled), 11 ns/op\nfind-my-way: GET /posts/search x 6,931,399 ops/sec ±0.16% (100 runs sampled), 144 ns/op\njson-joy router: POST /posts x 71,501,062 ops/sec ±0.91% (93 runs sampled), 14 ns/op\nfind-my-way: POST /posts x 13,755,641 ops/sec ±0.21% (98 runs sampled), 73 ns/op\njson-joy router: GET /posts/jhasdf982lsd x 20,794,603 ops/sec ±0.79% (97 runs sampled), 48 ns/op\nfind-my-way: GET /posts/jhasdf982lsd x 6,220,203 ops/sec ±0.17% (100 runs sampled), 161 ns/op\njson-joy router: POST /posts/jhasdf982lsd x 17,002,131 ops/sec ±0.24% (94 runs sampled), 59 ns/op\nfind-my-way: POST /posts/jhasdf982lsd x 6,783,108 ops/sec ±0.64% (98 runs sampled), 147 ns/op\njson-joy router: DELETE /posts/jhasdf982lsd x 18,912,944 ops/sec ±0.38% (95 runs sampled), 53 ns/op\nfind-my-way: DELETE /posts/jhasdf982lsd x 8,353,962 ops/sec ±0.84% (99 runs sampled), 120 ns/op\njson-joy router: GET /posts/jhasdf982lsd/tags x 16,857,334 ops/sec ±4.01% (92 runs sampled), 59 ns/op\nfind-my-way: GET /posts/jhasdf982lsd/tags x 5,169,375 ops/sec ±0.39% (98 runs sampled), 193 ns/op\njson-joy router: GET /posts/jhasdf982lsd/tags/top x 16,012,780 ops/sec ±0.38% (99 runs sampled), 62 ns/op\nfind-my-way: GET /posts/jhasdf982lsd/tags/top x 4,062,952 ops/sec ±0.65% (97 runs sampled), 246 ns/op\njson-joy router: GET /posts/jhasdf982lsd/tags/123 x 12,144,904 ops/sec ±0.21% (100 runs sampled), 82 ns/op\nfind-my-way: GET /posts/jhasdf982lsd/tags/123 x 4,036,060 ops/sec ±0.15% (98 runs sampled), 248 ns/op\njson-joy router: DELETE /posts/jhasdf982lsd/tags/123 x 11,797,726 ops/sec ±0.50% (94 runs sampled), 85 ns/op\nfind-my-way: DELETE /posts/jhasdf982lsd/tags/123 x 5,269,916 ops/sec ±0.10% (100 runs sampled), 190 ns/op\njson-joy router: POST /posts/jhasdf982lsd/tags x 15,483,784 ops/sec ±0.20% (100 runs sampled), 65 ns/op\nfind-my-way: POST /posts/jhasdf982lsd/tags x 5,586,607 ops/sec ±0.10% (100 runs sampled), 179 ns/op\njson-joy router: GET /api/collections x 89,443,474 ops/sec ±1.14% (93 runs sampled), 11 ns/op\nfind-my-way: GET /api/collections x 11,365,669 ops/sec ±0.15% (102 runs sampled), 88 ns/op\njson-joy router: POST /api/collections x 88,558,408 ops/sec ±1.15% (93 runs sampled), 11 ns/op\nfind-my-way: POST /api/collections x 11,427,491 ops/sec ±0.14% (98 runs sampled), 88 ns/op\njson-joy router: GET /api/collections/123 x 15,327,034 ops/sec ±0.21% (101 runs sampled), 65 ns/op\nfind-my-way: GET /api/collections/123 x 6,654,562 ops/sec ±0.10% (102 runs sampled), 150 ns/op\njson-joy router: PUT /api/collections/123 x 14,766,966 ops/sec ±0.23% (100 runs sampled), 68 ns/op\nfind-my-way: PUT /api/collections/123 x 7,446,186 ops/sec ±0.14% (99 runs sampled), 134 ns/op\njson-joy router: POST /api/collections/123 x 13,397,211 ops/sec ±0.23% (100 runs sampled), 75 ns/op\nfind-my-way: POST /api/collections/123 x 5,801,550 ops/sec ±6.34% (92 runs sampled), 172 ns/op\njson-joy router: DELETE /api/collections/123 x 16,470,990 ops/sec ±0.26% (99 runs sampled), 61 ns/op\nfind-my-way: DELETE /api/collections/123 x 6,618,101 ops/sec ±4.54% (90 runs sampled), 151 ns/op\njson-joy router: GET /api/collections/123/documents x 10,819,176 ops/sec ±20.48% (90 runs sampled), 92 ns/op\nfind-my-way: GET /api/collections/123/documents x 5,083,007 ops/sec ±0.10% (100 runs sampled), 197 ns/op\njson-joy router: POST /api/collections/123/documents x 11,471,312 ops/sec ±0.18% (101 runs sampled), 87 ns/op\nfind-my-way: POST /api/collections/123/documents x 5,024,672 ops/sec ±0.14% (97 runs sampled), 199 ns/op\njson-joy router: GET /api/collections/123/documents/456 x 8,776,775 ops/sec ±0.25% (98 runs sampled), 114 ns/op\nfind-my-way: GET /api/collections/123/documents/456 x 3,892,995 ops/sec ±0.30% (100 runs sampled), 257 ns/op\njson-joy router: PUT /api/collections/123/documents/456 x 9,946,515 ops/sec ±1.36% (97 runs sampled), 101 ns/op\nfind-my-way: PUT /api/collections/123/documents/456 x 4,347,762 ops/sec ±0.62% (98 runs sampled), 230 ns/op\njson-joy router: POST /api/collections/123/documents/456 x 8,120,919 ops/sec ±0.44% (99 runs sampled), 123 ns/op\nfind-my-way: POST /api/collections/123/documents/456 x 3,882,741 ops/sec ±1.26% (92 runs sampled), 258 ns/op\njson-joy router: DELETE /api/collections/123/documents/456 x 10,739,860 ops/sec ±0.89% (97 runs sampled), 93 ns/op\nfind-my-way: DELETE /api/collections/123/documents/456 x 4,483,659 ops/sec ±1.17% (98 runs sampled), 223 ns/op\njson-joy router: GET /api/collections/123/documents/456/revisions x 8,553,359 ops/sec ±0.91% (98 runs sampled), 117 ns/op\nfind-my-way: GET /api/collections/123/documents/456/revisions x 3,379,187 ops/sec ±0.17% (101 runs sampled), 296 ns/op\njson-joy router: GET /api/collections/123/documents/456/revisions/find x 8,092,442 ops/sec ±1.10% (97 runs sampled), 124 ns/op\nfind-my-way: GET /api/collections/123/documents/456/revisions/find x 2,829,474 ops/sec ±0.17% (100 runs sampled), 353 ns/op\njson-joy router: POST /api/collections/123/documents/456/revisions x 7,750,406 ops/sec ±0.93% (99 runs sampled), 129 ns/op\nfind-my-way: POST /api/collections/123/documents/456/revisions x 3,412,482 ops/sec ±0.14% (98 runs sampled), 293 ns/op\njson-joy router: GET /api/collections/123/documents/456/revisions/789 x 7,133,453 ops/sec ±0.51% (98 runs sampled), 140 ns/op\nfind-my-way: GET /api/collections/123/documents/456/revisions/789 x 2,851,795 ops/sec ±0.80% (95 runs sampled), 351 ns/op\njson-joy router: DELETE /api/collections/123/documents/456/revisions/789 x 8,168,205 ops/sec ±0.24% (96 runs sampled), 122 ns/op\nfind-my-way: DELETE /api/collections/123/documents/456/revisions/789 x 3,282,963 ops/sec ±0.10% (98 runs sampled), 305 ns/op\njson-joy router: GET /files/user123-movies/2019/01/01/1.mp4 x 13,990,918 ops/sec ±0.19% (100 runs sampled), 71 ns/op\nfind-my-way: GET /files/user123-movies/2019/01/01/1.mp4 x 5,132,706 ops/sec ±0.90% (101 runs sampled), 195 ns/op\njson-joy router: PUT /files/user123-movies/2019/01/01/1.mp4 x 13,951,426 ops/sec ±0.23% (99 runs sampled), 72 ns/op\nfind-my-way: PUT /files/user123-movies/2019/01/01/1.mp4 x 5,184,318 ops/sec ±0.23% (99 runs sampled), 193 ns/op\njson-joy router: GET /static/some/path/to/file.txt x 15,788,214 ops/sec ±1.06% (99 runs sampled), 63 ns/op\nfind-my-way: GET /static/some/path/to/file.txt x 8,104,177 ops/sec ±0.14% (100 runs sampled), 123 ns/op\nFastest is json-joy router: POST /ping,json-joy router: PUT /events,json-joy router: GET /ping\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsonjoy-com%2Fjit-router","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsonjoy-com%2Fjit-router","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsonjoy-com%2Fjit-router/lists"}