英文:
Dynamically instantiating HandleFunc
问题
我一直在努力理解如何以动态方式实现HandleFunc()
。
我想将这个yaml文件转换为Go语言中的本地HTTP Web服务器。
# Example .mock.yaml config
Endpoints:
- Resource: /city/1
Method: GET
Response: '{ "Id": 1, "Name": "Albuquerque", "Population": 559.374, "State": "New Mexico" }'
StatusCode: 200
- Resource: /city
Method: POST
Response: '{ "Name": "Albuquerque", "Population": 559.374, "State": "New Mexico" }'
StatusCode: 200
- Resource: /city/1
Method: PUT
Response: '{ "Population": 601.255 }'
StatusCode: 204
- Resource: /city/1
Method: DELETE
StatusCode: 204
现在我成功实现了以下代码:
package utils
import (
"io"
"net/http"
"github.com/gorilla/mux"
"github.com/bschaatsbergen/mock/model"
)
func StartServer(conf model.Config, port string) {
r := mux.NewRouter()
for _, endpoint := range conf.Endpoints {
r.HandleFunc(endpoint.Resource, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(endpoint.StatusCode)
io.WriteString(w, endpoint.Response)
}).Methods(endpoint.Method)
}
address := ":" + port
http.ListenAndServe(address, r)
}
但是这样做不够好,因为它会覆盖先前创建的路由('/city/1'的GET、DELETE和POST方法冲突)。
如果有人能帮我解决如何将yaml配置动态转换为本地Web服务器,我将不胜感激!
英文:
I've been trying to wrap my head around implementing HandleFunc()
in a dynamic way.
This yaml file I want to turn into a local http web server in Go.
# Example .mock.yaml config
Endpoints:
- Resource: /city/1
Method: GET
Response: '{ Id": 1, "Name": "Albuquerque", "Population": 559.374, "State": "New Mexico" }'
StatusCode: 200
- Resource: /city
Method: POST
Response: '{ "Name": "Albuquerque", "Population": 559.374, "State": "New Mexico" }'
statusCode: 200
- Resource: /city/1
Method: PUT
Response: '{ "Population": 601.255 }'
StatusCode: 204
- Resource: /city/1
Method: DELETE
StatusCode: 204
Now I managed to implement something as following:
package utils
import (
"io"
"net/http"
"github.com/gorilla/mux"
"github.com/bschaatsbergen/mock/model"
)
func StartServer(conf model.Config, port string) {
r := mux.NewRouter()
for _, endpoint := range conf.Endpoints {
r.HandleFunc(endpoint.Resource, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(endpoint.StatusCOde)
io.WriteString(w, endpoint.Response)
}).Methods(endpoint.Method)
}
address := ":" + port
http.ListenAndServe(address, r)
}
^ https://play.golang.org/p/YoTTUKnQL_5
But this doesn't cut it as it overwrites an earlier created route ('/city/1' GET, DELETE and POST are conflicting).
If anyone could give me a hand on how to dynamically translate the yaml config into a local web server, it would be appreciated!
答案1
得分: 2
我引用了@mkopriva的话,谢谢!
> 我相当确定你的问题与这里的问题相同:
> stackoverflow.com/questions/69595865/…。也就是说,你所有的匿名处理程序闭包都捕获了同一个变量,即迭代变量,在循环结束时,它将保存Endpoints切片的最后一个元素。正确吗?这个问题可以关闭为重复吗?
工作的代码片段:
func StartServer(conf model.Config, port string) {
r := mux.NewRouter()
for _, endpoint := range conf.Endpoints {
route := endpoint
r.HandleFunc(route.Resource, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(route.Statuscode)
io.WriteString(w, route.Response)
}).Methods(route.Method)
}
address := ":" + port
log.Fatal(http.ListenAndServe(address, r))
}
英文:
I quote from @mkopriva, thanks!
> I'm fairly certain your problem is the same as the one here:
> stackoverflow.com/questions/69595865/…. i.e. All of your anon handler
> closures capture one and the same variable, the iteration variable,
> which, at the end of the loop, will hold the last element of the
> Endpoints slice. Correct? Can the question be closed as duplicate?
Working piece of code:
func StartServer(conf model.Config, port string) {
r := mux.NewRouter()
for _, endpoint := range conf.Endpoints {
route := endpoint
r.HandleFunc(route.Resource, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(route.Statuscode)
io.WriteString(w, route.Response)
}).Methods(route.Method)
}
address := ":" + port
log.Fatal(http.ListenAndServe(address, r))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论