feat: add hono.route method for easy group requests

This commit is contained in:
yangshangbo
2025-04-18 19:02:04 +08:00
parent 7734b328b2
commit a76ad033b0
3 changed files with 77 additions and 33 deletions
+50 -20
View File
@@ -10,6 +10,7 @@ type Handler = fn (req Request) http.Response
struct RequestHandler { struct RequestHandler {
path string path string
handler Handler = unsafe { nil } handler Handler = unsafe { nil }
mut: app Hono
} }
struct Router { struct Router {
@@ -30,37 +31,41 @@ pub struct Hono {
mut: mut:
server http.Server = http.Server{} server http.Server = http.Server{}
router Router = Router{} router Router = Router{}
routes map[string] Hono = {}
base_path string
} }
pub fn (mut app Hono) get(path string, handler Handler) { pub fn (mut app Hono) get(path string, handler Handler) {
app.router.handlers.get << RequestHandler{path, handler} mut handlers := RequestHandler{path,handler,app}
app.router.handlers.get << handlers
} }
pub fn (mut app Hono) post(path string, handler Handler) { pub fn (mut app Hono) post(path string, handler Handler) {
app.router.handlers.post << RequestHandler{path, handler} app.router.handlers.post << RequestHandler{path,handler,app}
} }
pub fn (mut app Hono) put(path string, handler Handler) { pub fn (mut app Hono) put(path string, handler Handler) {
app.router.handlers.put << RequestHandler{path, handler} app.router.handlers.put << RequestHandler{path,handler,app}
} }
pub fn (mut app Hono) delete(path string, handler Handler) { pub fn (mut app Hono) delete(path string, handler Handler) {
app.router.handlers.delete << RequestHandler{path, handler} app.router.handlers.delete << RequestHandler{path,handler,app}
} }
pub fn (mut app Hono) patch(path string, handler Handler) { pub fn (mut app Hono) patch(path string, handler Handler) {
app.router.handlers.patch << RequestHandler{path, handler} app.router.handlers.patch << RequestHandler{path,handler,app}
} }
pub fn (mut app Hono) head(path string, handler Handler) { pub fn (mut app Hono) head(path string, handler Handler) {
app.router.handlers.head << RequestHandler{path, handler} app.router.handlers.head << RequestHandler{path,handler,app}
} }
pub fn (mut app Hono) options(path string, handler Handler) { pub fn (mut app Hono) options(path string, handler Handler) {
app.router.handlers.options << RequestHandler{path, handler} app.router.handlers.options << RequestHandler{path,handler,app}
} }
struct ServerHanler { struct ServerHanler {
mut:
app Hono app Hono
} }
@@ -93,44 +98,55 @@ fn match_path_with_regex(real_path string, reg_path string) (bool, regex.RE) {
return reg.matches_string(real_path), reg return reg.matches_string(real_path), reg
} }
fn (s ServerHanler) handle(req http.Request) http.Response { fn get_all_handlers_from_hono(app Hono,req http.Request) []RequestHandler {
mut res := http.Response{ mut result := []RequestHandler{}
status_code: 404
body: 'Not Found'
}
handlers := match req.method { handlers := match req.method {
.get { .get {
s.app.router.handlers.get app.router.handlers.get
} }
.post { .post {
s.app.router.handlers.post app.router.handlers.post
} }
.put { .put {
s.app.router.handlers.put app.router.handlers.put
} }
.delete { .delete {
s.app.router.handlers.delete app.router.handlers.delete
} }
.patch { .patch {
s.app.router.handlers.patch app.router.handlers.patch
} }
.head { .head {
s.app.router.handlers.head app.router.handlers.head
} }
.options { .options {
s.app.router.handlers.options app.router.handlers.options
} }
else { else {
[] []
} }
} }
result << handlers
for key in app.routes.keys() {
subapp_handlers := get_all_handlers_from_hono(app.routes[key],req)
result << subapp_handlers
}
return result
}
fn (s ServerHanler) handle(req http.Request) http.Response {
mut res := http.Response{
status_code: 404
body: 'Not Found'
}
handlers := get_all_handlers_from_hono(s.app,req)
for handler in handlers { for handler in handlers {
url := urllib.parse(req.url) or { url := urllib.parse(req.url) or {
urllib.URL{ urllib.URL{
path: '/' path: '/'
} }
} }
match_result, mut replaced_path_reg := match_path_with_regex(url.path, handler.path) match_result, mut replaced_path_reg := match_path_with_regex(url.path, handler.app.base_path + handler.path)
if match_result { if match_result {
mut param_map := map[string]string{} mut param_map := map[string]string{}
mut pamam_reg := regex.regex_opt(r':\w+') or { panic(err) } mut pamam_reg := regex.regex_opt(r':\w+') or { panic(err) }
@@ -157,3 +173,17 @@ pub fn (mut app Hono) listen(port string) {
app.server.handler = ServerHanler.new(app) app.server.handler = ServerHanler.new(app)
app.server.listen_and_serve() app.server.listen_and_serve()
} }
pub fn (mut app Hono) route(prefix string,mut subapp Hono) {
for mut request_handler in subapp.router.handlers.get {
request_handler.app.base_path = prefix
}
for mut request_handler in subapp.router.handlers.post {
request_handler.app.base_path = prefix
}
app.routes[prefix] = subapp
}
pub fn (mut app Hono) set_base_path(base_path string) {
app.base_path = base_path
}
+6
View File
@@ -70,6 +70,12 @@ fn main() {
status_code: 200 status_code: 200
} }
}) })
mut book_app := &hono.Hono{}
book_app.get('/api/book', fn (req hono.Request) http.Response {
println('Received get request: ${req}')
return hono.Response.text('books')
})
hono_app.route('/api', mut book_app)
port := '0.0.0.0:8585' port := '0.0.0.0:8585'
hono_app.listen(port) hono_app.listen(port)
println('Listening on ${port}') println('Listening on ${port}')
+21 -13
View File
@@ -1,14 +1,22 @@
import regex // import regex
import pcre
fn main(){ fn main() {
path := "/order/**" // path := '/order/**'
mut replaced_path := path.replace('**','[\\w+//?]+') // mut replaced_path := path.replace('**','[\\w+//?]+')
println("replaced_path: ${replaced_path}") // println("replaced_path: ${replaced_path}")
replaced_path = replaced_path.replace('*','\\w+') // replaced_path = replaced_path.replace('*','\\w+')
println("replaced_path: ${replaced_path}") // println("replaced_path: ${replaced_path}")
replaced_path = replaced_path + '$' // replaced_path = replaced_path + '$'
println("replaced_path: ${replaced_path}") // println("replaced_path: ${replaced_path}")
mut reg := regex.regex_opt(replaced_path) or { panic(err) } // mut reg := regex.regex_opt(replaced_path) or { panic(err) }
result := reg.matches_string("/order/33") // result := reg.matches_string("/order/33")
println("reg match result ${result}") mut reg := pcre.new_regex(r'/(?:order)/[\w+/]+', 0) or { panic(err) }
} result := reg.match_str('555/order/33//?88/', 0, 0) or { panic(err) }
mut count := 0
for count < result.group_size {
println('group ${count} ${result.get(count) or { 'not found' }}')
count++
}
println('reg match result ${result}')
}