英文:
Go HTTP Server: Handling Routes with Map
问题
我在Go语言中有一个map
,其中键是路由(例如/static/stylesheets/main.css
),值是相应的代码(实际上是一个巨大的字符串)。我想知道,在Go语言中是否有一种简单的方法可以创建一个HTTP服务器,该服务器始终将传入的请求与map
进行匹配,并在存在匹配键的情况下呈现与之关联的值?
到目前为止,我有以下代码...
func main() {
var m = generateMap()
http.HandleFunc("/", renderContent)
}
func renderContent(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, m[path])
}
我知道这段代码还远未完成,但希望它能澄清我的目标。我应该如何将path
和m
传递给renderContent
函数?另外,handleFunc
如何处理正则表达式(实际上是任意路径)?
英文:
I have a map
in Go with routes (e.g. /static/stylesheets/main.css
) as keys and the corresponding code as the value (effectively, a giant string). I was just wondering, is there an easy way in Go by which I can create an HTTP server, which always check an incoming request against the map
and renders the value associated with the matched key, if the key exists?
So far, I have...
<!-- language: lang-js -->
func main() {
var m = generateMap()
http.handleFunc("/", renderContent);
}
func renderContent(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, m[path]);
}
I know this code is far from done, but hopefully it clarifies my objective. How would I pass in the path
and m
into renderContent
as well as how do I have handleFunc
actually handle regexes (essentially, any path)?
答案1
得分: 2
如果你不介意不亲自编写代码,想要一个小而快速的解决方案,可以考虑使用gorilla mux。他们的工具包允许你选择你想要的组件,所以如果你只想要使用正则表达式进行路由,只需添加他们的mux即可。
我发现它在从路由中获取变量方面特别有帮助。
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
...
vars := mux.Vars(request)
category := vars["category"]
英文:
If you're open to not writing it yourself, something small quick and out of the box - look at gorilla mux. Their toolkit lets you choose the components you want, so just add their mux if all you want is routing with regex.
I found it particularly helpful for obtaining variable from routes.
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler)
...
vars := mux.Vars(request)
category := vars["category"]
答案2
得分: 1
将你的地图转换为 http.Handler
:
type httpFiles struct {
fileMap map[string][]byte
}
func (hf httpFiles) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
w.Write(hf.fileMap[path])
}
英文:
Make your map an http.Handler
:
type httpFiles struct {
fileMap map[string][]byte
}
func (hf httpFiles) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
w.Write(hf.fileMap[path])
}
答案3
得分: 1
我推荐使用httprouter作为最快的Go路由器。Go的内置mux不完整且速度较慢,没有简便的方法来捕获URL参数。
此外,当你有多个路由时,你可以考虑将每个路由作为一个结构体,这样处理起来更容易。
以下代码捕获URL参数,将其与映射的关键字进行比较,并将代码块的字符串打印到控制台。
package main
import (
"fmt"
"net/http"
"log"
mux "github.com/julienschmidt/httprouter"
)
type Route struct {
Name string
Method string
Pattern string
Handle mux.Handle
}
var codeChunk = map[string]string{ "someUrlPath" : "func printHello(){\n\tfmt.Println(\"Hello\")\n}" }
var route = Route{
"MyHandler",
"GET",
"/:keywordUrl",
MyHandler,
}
func MyHandler(w http.ResponseWriter, r *http.Request, ps mux.Params) {
// 处理路由"/:keywordUrl"
w.WriteHeader(http.StatusOK)
// 从URL中获取参数
path := ps.ByName("keywordUrl")
for key, value := range codeChunk {
// 将参数与映射的键进行比较
if key != "" && path == key {
// 做一些操作
fmt.Println(value)
}
}
}
func main() {
router := mux.New()
router.Handle(route.Method, route.Pattern, route.Handle)
log.Fatal(http.ListenAndServe(":8080", router))
// 浏览到http://localhost:8080/someUrlPath,可以看到映射的字符串值被打印出来。
}
英文:
I recommend package httprouter being the fastest go router around. Go's built-in mux is incomplete and slow without an easy way to capture URL parameters.
Also, you might consider making each route a struct so it's easier to handle when you have several routes.
This code captures URL parameter, compare it to the keyword of the map and print the string of code chunk to the console.
package main
import (
"fmt"
"net/http"
"log"
mux "github.com/julienschmidt/httprouter"
)
type Route struct {
Name string
Method string
Pattern string
Handle mux.Handle
}
var codeChunk = map[string]string{ "someUrlPath" : "func printHello(){\n\tfmt.Println(\"Hello\")\n}" }
var route = Route{
"MyHandler",
"GET",
"/:keywordUrl",
MyHandler,
}
func MyHandler(w http.ResponseWriter, r *http.Request, ps mux.Params) {
// Handle route "/:keywordUrl"
w.WriteHeader(http.StatusOK)
// get the parameter from the URL
path := ps.ByName("keywordUrl")
for key, value := range codeChunk {
// Compare the parameter to the key of the map
if key != "" && path == key {
// do something
fmt.Println(value)
}
}
}
func main() {
router := mux.New()
router.Handle(route.Method, route.Pattern, route.Handle)
log.Fatal(http.ListenAndServe(":8080", router))
// browse to http://localhost:8080/someUrlPath to see
// the map's string value being printed.
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论