Go HTTP服务器:使用Map处理路由

huangapple go评论84阅读模式
英文:

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])
}

我知道这段代码还远未完成,但希望它能澄清我的目标。我应该如何将pathm传递给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(&quot;/&quot;, 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(&quot;/articles/{category}/{id:[0-9]+}&quot;, ArticleHandler)
...

vars := mux.Vars(request)
category := vars[&quot;category&quot;]

答案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 (
    &quot;fmt&quot;
    &quot;net/http&quot;
    &quot;log&quot;
    mux &quot;github.com/julienschmidt/httprouter&quot;
)

type Route struct {
    Name        string
    Method      string
    Pattern     string
    Handle      mux.Handle

}

var codeChunk = map[string]string{ &quot;someUrlPath&quot; : &quot;func printHello(){\n\tfmt.Println(\&quot;Hello\&quot;)\n}&quot; }

var route = Route{
    &quot;MyHandler&quot;,
    &quot;GET&quot;,
    &quot;/:keywordUrl&quot;,
    MyHandler,
}

func MyHandler(w http.ResponseWriter, r *http.Request, ps mux.Params) {

    // Handle route &quot;/:keywordUrl&quot;
    w.WriteHeader(http.StatusOK)

    // get the parameter from the URL
    path := ps.ByName(&quot;keywordUrl&quot;)

    for key, value := range codeChunk {
        // Compare the parameter to the key of the map
        if key != &quot;&quot; &amp;&amp; path == key {
            // do something
            fmt.Println(value)
        }
    }
}

func main() {
    router := mux.New()
    router.Handle(route.Method, route.Pattern, route.Handle)

    log.Fatal(http.ListenAndServe(&quot;:8080&quot;, router))

    // browse to http://localhost:8080/someUrlPath to see 
    // the map&#39;s string value being printed.
}

huangapple
  • 本文由 发表于 2015年8月11日 23:24:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/31945875.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定