有没有更简单的方法来使用net/http实现JSON REST服务?

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

Is there a simpler way to implement a JSON REST service with net/http?

问题

我正在尝试使用net/http开发一个REST服务。

该服务接收一个包含所有输入参数的JSON结构。我想知道是否有一种更简单、更短的方法来实现以下代码:

func call(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseForm(); err != nil {
        fmt.Printf("Error parsing request %s\n", err)
    }
    var buf []byte
    buf = make([]byte, 256)
    var n, err = r.Body.Read(buf)
    var decoded map[string]interface{}
    err = json.Unmarshal(buf[:n], &decoded)
    if err != nil {
        fmt.Printf("Error decoding json: %s\n", err)
    }
    var uid = decoded["uid"]
    ...
}

如你所见,为了提取第一个参数,需要相当多的代码行。有什么想法吗?

英文:

I am trying to develop a REST service with net/http.

The service receives a JSON structure containing all the input parameters. I wonder if there is an easier and shorter way to implement the following:

func call(w http.ResponseWriter, r *http.Request) {
    if err := r.ParseForm(); err != nil {
    	fmt.Printf("Error parsing request %s\n", err)
    }
    var buf []byte
    buf = make([]byte, 256)
    var n, err = r.Body.Read(buf)
    var decoded map[string]interface{}
    err = json.Unmarshal(buf[:n], &decoded)
    if err != nil {
	    fmt.Printf("Error decoding json: %s\n", err)
    }
    var uid = decoded["uid"]
    ...
}

As you can see it requires quite a number of lines just to get to the extraction of the first parameter. Any ideas?

答案1

得分: 6

你不需要调用r.ParseForm,如果请求的主体包含一个JSON结构,并且你不需要任何URL参数。

你也不需要缓冲区,可以使用:

decoder := json.NewDecoder(r.Body)

然后:

error := decoder.Decode(decoded)

将它们整合在一起:

func call(w http.ResponseWriter, r *http.Request) {

    values := make(map[string]interface{})

    if error := json.NewDecoder(r.Body).Decode(&values); error != nil {
        panic(error)
    }

    uid := values["uid"].(int)

}

不过,如果你能正式定义你期望的输入结构的结构类型,会更好:

type UpdateUserInformationRequest struct {
    UserId int `json:"uid"`
    // 其他字段...
}

并且使用该结构的实例,而不是更通用的map。

英文:

You don't need to call r.ParseForm if the body of the request will contain a JSON structure and you don't need any URL parameters.

You don't need the buffer either; you can use:

decoder := json.NewDecoder(r.Body)

And then:

error := decoder.Decode(decoded)

Putting it all together:

func call(w http.ResponseWriter, r *http.Request) {

    values := make(map[string]interface{})

    if error := json.NewDecoder(r.Body).Decode(&values); error != nil {
        panic(error)
    }

    uid := values["uid"].(int)

}

It would be much nicer, though, if you could formally define the structure of the input that you're expecting in a struct type:

type UpdateUserInformationRequest struct {
    UserId int `json:"uid"`
    // other fields...
}

And use an instance of this struct instead of a more general map.

huangapple
  • 本文由 发表于 2014年5月12日 18:48:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/23606981.html
匿名

发表评论

匿名网友

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

确定