I am trying to create a tree like radix tree for http routing
My code:
interface Node {
nodes?: Record<string, Node>
methods?: Record<string, () => unknown>
}
class Tree {
root: Node
constructor() {
this.root = {}
}
insert(path: string, method: string, handler: () => unknown): void {
let node = this.root
path.split('/').forEach((path: string): void => {
path = path === '' ? '/' : path
node.nodes = node.nodes ?? {}
const child = node.nodes[path] ?? {}
node.nodes[path] = child
node = child
})
node.methods = node.methods ?? {}
if (!node.methods[method]) {
node.methods[method] = handler
}
}
}
const tree = new Tree()
tree.insert('/users', 'GET', (): string => {
return 'users get handler'
})
tree.insert('/posts', 'GET', (): string => {
return 'posts get handler'
})
tree.insert('/profile', 'GET', (): string => {
return 'profile get handler'
})
tree.insert('/profile/posts', 'GET', (): string => {
return 'profile posts get handler'
})
tree.insert('/profile/friends', 'GET', (): string => {
return 'profile friends get handler'
})
console.log(
JSON.stringify(tree),
)
Expected result:
{
root: {
nodes: {
"/": {
nodes: {
users: {
methods: {
GET: handler,
},
},
posts: {
methods: {
GET: handler,
},
},
profile: {
methods: {
GET: handler,
},
nodes: {
posts: {
methods: {
GET: handler,
},
},
friends: {
methods: {
GET: handler,
},
},
},
},
},
},
},
},
}
I would like to replace the root variable with nodes in the Tree class:
class Tree {
nodes: Record<string, Node>
}
To get the desired result:
{
nodes: {
"/": {
nodes: {
users: {
methods: {
GET: handler,
},
},
posts: {
methods: {
GET: handler,
},
},
profile: {
methods: {
GET: handler,
},
nodes: {
posts: {
methods: {
GET: handler,
},
},
friends: {
methods: {
GET: handler,
},
},
},
},
},
},
},
}
I tried several times to implement what I wanted, but in the end I got confused with my own code...
PS: Thank you all in advance for your answers :)
CodePudding user response:
To achieve that your class works with a nodes
member instead of root
, you only need to change the first statement in your insert
method.
Replace:
let node = this.root
with:
let node = { nodes: this.nodes };