Skip to content

Commit

Permalink
Added support for path parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
vanodevium committed Oct 24, 2019
1 parent 16ce342 commit 073975d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
12 changes: 11 additions & 1 deletion README.md
Expand Up @@ -20,6 +20,8 @@ import {

app(
get('/hello', () => 'hello'),
get('/hello/:id', ({ params }) => params.id),
get('/hello/:id/and/:name', ({ params }) => `:id is ${params.id}, :name is ${params.name}`),
get('/error', () => [500, 'an error has occured']),
get('/callName', ({ params }) => `Hi, ${params.name}!`),
post('/callName', ({ params }) => `Hi, ${params.name}!`),
Expand All @@ -39,6 +41,14 @@ curl http://localhost:8080/hello
# status: 200
# body: hello

curl http://localhost:8080/hello/1
# status: 200
# body: 1

curl http://localhost:8080/hello/1/and/John
# status: 200
# body: :id is 1, :name is John

curl http://localhost:8080/error
# status: 500
# body: an error has occured
Expand Down Expand Up @@ -160,7 +170,7 @@ interface HTTPResponse {
### Request Params

- [x] URL query params (for GET)
- [ ] route params (like: `/users/:user_id/posts`)
- [x] route params (like: `/users/:user_id/posts`)
- [x] x-www-form-urlencoded
- [x] application/json

Expand Down
2 changes: 2 additions & 0 deletions example/index.ts
Expand Up @@ -2,6 +2,8 @@ import { app, get, post, contentType } from '../mod.ts';

app(
get('/hello', () => 'hello'),
get('/hello/:id', ({ params }) => params.id),
get('/hello/:id/and/:name', ({ params }) => `:id is ${params.id}, :name is ${params.name}`),
get('/error', () => [500, 'an error has occured']),
get('/callName', ({ params }) => `Hi, ${params.name}!`),
post('/callName', ({ params }) => `Hi, ${params.name}!`),
Expand Down
33 changes: 31 additions & 2 deletions mod.ts
Expand Up @@ -87,12 +87,41 @@ export class App {
return null;
}

const handler = map.get(path);
const params: Params = {};

let handler;

const REGEX_URI_MATCHES = /(:[^/]+)/g;
const REGEX_URI_REPLACEMENT = "([^/]+)";
const URI_PARAM_MARKER = ':';

Array.from(map.keys()).forEach((endpoint) => {
if (endpoint.indexOf(URI_PARAM_MARKER) !== -1) {
const matcher = endpoint.replace(REGEX_URI_MATCHES, REGEX_URI_REPLACEMENT);
const matches = path.match(`^${matcher}$`);

if (matches === null) {
return
}

const names = endpoint.match(REGEX_URI_MATCHES).map(name => name.replace(URI_PARAM_MARKER, ''));

matches.slice(1).forEach((m, i) => {
params[names[i]] = m
});

handler = map.get(endpoint)
}
});

if (!handler) {
handler = map.get(path)
}

if (!handler) {
return null;
}

const params: Params = {};
if (method === Method.GET) {
if (search) {
Object.assign(params, parseURLSearchParams(search));
Expand Down
21 changes: 21 additions & 0 deletions serve_test.ts
Expand Up @@ -35,6 +35,27 @@ const testCases: Array<testCase> = [
method: Method.GET,
expected: 'basic',
},
{
name: 'valid basic handler with path parameter',
registered: get('/parameters/:param', ({ params }) => params.param),
path: 'parameters/p',
method: Method.GET,
expected: 'p',
},
{
name: 'valid basic handler with path parameters',
registered: get('/parameters/:param1/:param2', ({ params }) => `${params.param1} ${params.param2}`),
path: 'parameters/p1/p2',
method: Method.GET,
expected: 'p1 p2',
},
{
name: 'valid basic handler with path parameter at start',
registered: get('/:param', ({ params }) => params.param),
path: 'basic',
method: Method.GET,
expected: 'basic',
},
{
name: 'valid async handler',
registered: get('/async', async () => 'async'),
Expand Down

0 comments on commit 073975d

Please sign in to comment.