DEV Community

Cover image for Updated My Custom Router
Kenta Takeuchi
Kenta Takeuchi

Posted on • Originally published at bmf-tech.com

Updated My Custom Router

This article was originally published on bmf-tech.com.

Overview

Recently, I updated my custom router, goblin, and I wanted to document the changes.

Here are some past articles about routing. There are also articles from the implementation consideration phase, but the content wasn't very good, so I'll omit them.

What Has Changed?

I had released a version with basic functionality as 1.0.0. While using it myself, I found bugs and felt the lack of features, leading to several backward-incompatible changes (a result of haphazard implementation), and now the latest version is 5.0.1.

The most significant change is the support for middleware, which led to a review of the internal data structure, DSL, and bug fixes.

Why Support Middleware?

I thought middleware could be freely handled by the router users, but there were constraints.

Even if middleware was implemented by the user, it would execute after the routing matching process (i.e., whether the path and HTTP method match the registered routing), which imposed a restriction that middleware couldn't be applied before HTTP method matching.

This was inconvenient when handling preflight requests (like CORS), so I decided to support middleware to fundamentally solve this issue.

The tricky part in considering such cases was the internal data structure of the routing, which was based on the assumption of path and HTTP method matching, so it needed to be reviewed.

Therefore, I changed the data structure as follows and implemented middleware support.

Before
Based on trie tree

After
after

Benchmark

I had written benchmarks for static routing only, but I wanted to compare with other libraries in dynamic routing tests, so I used the most comprehensive github.com - julienschmidt/go-http-routing-benchmark for benchmark testing.

Here are the latest scores.

#GithubAPI Routes: 203
   Goblin: 80864 Bytes

#GPlusAPI Routes: 13
   Goblin: 7856 Bytes

#ParseAPI Routes: 26
   Goblin: 8688 Bytes

#Static Routes: 157
   Goblin: 34488 Bytes

goos: darwin
goarch: amd64
pkg: github.com/julienschmidt/go-http-routing-benchmark
cpu: Intel(R) Core(TM) i5-8210Y CPU @ 1.60GHz
BenchmarkGoblin_Param             738289              1964 ns/op             128 B/op          4 allocs/op
BenchmarkGoblin_Param5            754988              1920 ns/op             368 B/op          6 allocs/op
BenchmarkGoblin_Param20            56145             23260 ns/op            3168 B/op         58 allocs/op
BenchmarkGoblinWeb_ParamWrite     304082              4610 ns/op             648 B/op         11 allocs/op
BenchmarkGoblin_GithubStatic     1156518              2745 ns/op             128 B/op          4 allocs/op
BenchmarkGoblin_GithubParam       125570              9985 ns/op             816 B/op         15 allocs/op
BenchmarkGoblin_GithubAll           2232            622376 ns/op           49424 B/op       1018 allocs/op
BenchmarkGoblin_GPlusStatic      1000000              1298 ns/op              80 B/op          3 allocs/op
BenchmarkGoblin_GPlusParam        417717              2893 ns/op             664 B/op         11 allocs/op
BenchmarkGoblin_GPlus2Params      274990              4551 ns/op             824 B/op         15 allocs/op
BenchmarkGoblin_GPlusAll           95580             14536 ns/op            2208 B/op         57 allocs/op
BenchmarkGoblin_ParseStatic      1651083               707.0 ns/op           128 B/op          4 allocs/op
BenchmarkGoblin_ParseParam        413840              2876 ns/op             728 B/op         12 allocs/op
BenchmarkGoblin_Parse2Params      260120              4119 ns/op             808 B/op         15 allocs/op
BenchmarkGoblin_ParseAll           54518             21692 ns/op            4656 B/op        120 allocs/op
BenchmarkGoblin_StaticAll          26689             46104 ns/op               0 B/op          0 allocs/op
PASS
ok      github.com/julienschmidt/go-http-routing-benchmark      37.270s
Enter fullscreen mode Exit fullscreen mode

I have submitted a PR to add goblin's benchmark support.
github.com - julienschmidt/go-http-routing-benchmark Add a new router goblin #97

Thoughts

I feel like it has finally become a decent router. There are still many areas for improvement, so I will continue to maintain it.

Top comments (0)