Manipulating JSON in Go ReST service that uses Gorilla

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

Manipulating JSON in Go ReST service that uses Gorilla

问题

我有一个接收 JSON 的 Go ReST 服务,我需要编辑 JSON 以便创建两个不同的结构体。

我的结构体:

type Interaction struct {
	DrugName      string `json:"drugName"`
	SeverityLevel string `json:"severityLevel"`
	Summary       string `json:"summary"`
}

type Drug struct {
	Name         string       `json:"drugName"`
	Dosages      []string     `json:"dosages"`
	Interactions []Interaction `json:"interactions"`
}

示例发送的 JSON:

{
	"drugName": "foo",
	"dosages": ["dos1"],
	"interactions": [["advil", "high", "summaryForAdvil"]]
}

ReST 服务:

func CreateDrug(w http.ResponseWriter, r *http.Request) {
	// 通过打印字节验证接收到的 JSON:
	bytes, _ := ioutil.ReadAll(r.Body)
}

我的目标是在 CreateDrug 函数中创建两个不同的 JSON,以便创建两个不同的结构体 Drug 和 Interaction:

{"drugName": "foo", "dosages": ["dos1"]}
{"drugName": "advil", "severityLevel": "high", "summary": "summaryForAdvil"}

在 Go 中,我该如何使用接收到的 JSON 来创建两个新的 JSON?

英文:

I have a Go ReST service that receives JSON, and I need to edit the JSON so I may make two different structs.

My structs:

type Interaction struct{

 DrugName string `json:"drugName"`
 SeverityLevel string `json:"severityLevel"`
 Summary string `json:"summary"`
}

type Drug struct {
 Name string `json:"drugName"`
 Dosages []string `json:"dosages"`
 Interactions []Interaction `json:"interactions"`
}

Example JSON being sent:

{"drugName":"foo","dosages":["dos1"],"interactions":[["advil","high","summaryForAdvil"]]}

The ReST service:

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

  //I verified the received JSON by printing out the bytes:
  bytes, _ := ioutil.ReadAll(r.Body)
}

My goal is the make two different JSONs in the CreateDrug function so I may make the two different structs, Drug and Interaction:

{"drugName":"foo","dosages":["dos1"]}
{"drugName":"advil", "severityLevel":"high", "summary":"summaryForAdvil"}

In Go, in this function, how do I use the received JSON to make two new JSONs?

答案1

得分: 0

将请求解组为与请求结构匹配的结构体,将值复制到您定义的结构体中,并进行编组以创建结果。

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

  // 将请求解组为与传入JSON结构匹配的值

  var v struct {
    DrugName     string
    Dosages      []string
    Interactions [][3]string
  }
  if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
    // 处理错误
  }

  // 复制到新的结构体值。

  var interactions []Interaction
  for _, i := range v.Interactions {
    interactions = append(interactions, Interaction{DrugName: i[0], SeverityLevel: i[1], Summary: i[2]})
  }

  drug := &Drug{Name: v.DrugName, Dosages: v.Dosages, Interactions: interactions}

  // 编组回JSON。

  data, err := json.Marshal(drug)
  if err != nil {
    // 处理错误
  }

  // 处理数据。
}

(我假设您希望Drug具有填充了Interactions字段的单个JSON值。如果这不是您想要的,请分别编组Drug和Interactions值。)

Playground链接

英文:

Unmarshal the request to a struct matching the structure of the request, copy values to the structs you have defined, and marshal to create the result.

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

  // Unmarshal request to value matching the structure of the incoming JSON

  var v struct {
	DrugName     string
	Dosages      []string
	Interactions [][3]string
  }
  if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
    // handle error
  }

  // Copy to new struct values.

  var interactions []Interaction
  for _, i := range v.Interactions {
	interactions = append(interactions, Interaction{DrugName: i[0], SeverityLevel: i[1], Summary: i[2]})
  }

  drug := &Drug{Name: v.DrugName, Dosages: v.Dosages, Interactions: interactions}

  // Marshal back to JSON.

  data, err := json.Marshal(drug)
  if err != nil {
      // handle error
  }

  // Do something with data.
}

<kbd>Playground link</kbd>

(I am assuming that you want a single JSON value for Drug with the Interactions field filled in. If that's not what you want, marshal the Drug and Interactions values separately.)

答案2

得分: 0

你可以使用json.Encoder将多个json结构输出到流中,只需解码输入的json即可。这里是一个简单的示例:

type restValue struct {
    Name         string      `json:"drugName"`
    Dosages      []string    `json:"dosages"`
    Interactions [][3]string `json:"interactions"`
}

func main() {
    d := []byte(`{"drugName":"foo","dosages":["dos1"],"interactions":[["advil","high","summaryForAdvil"]]}`)
    var v restValue
    if err := json.Unmarshal(d, &v); err != nil {
        panic(err)
    }
    interactions := make([]Interaction, 0, len(v.Interactions))
    for _, in := range v.Interactions {
        interactions = append(interactions, Interaction{in[0], in[1], in[2]})
    }
    drug := &Drug{Name: v.Name, Dosages: v.Dosages, Interactions: interactions}
    enc := json.NewEncoder(os.Stdout)
    // 如果你想要整个Drug结构
    enc.Encode(drug)

    // 或者如果你想要两个不同的结构:
    drug = &Drug{Name: v.Name, Dosages: v.Dosages}
    enc.Encode(drug)
    for _, in := range interactions {
        enc.Encode(in)
    }
}

playground

英文:

You can use json.Encoder and output multiple json structs to a stream, you just have to decode the input json, here's a simple example:

type restValue struct {
	Name         string      `json:&quot;drugName&quot;`
	Dosages      []string    `json:&quot;dosages&quot;`
	Interactions [][3]string `json:&quot;interactions&quot;`
}

func main() {
	d := []byte(`{&quot;drugName&quot;:&quot;foo&quot;,&quot;dosages&quot;:[&quot;dos1&quot;],&quot;interactions&quot;:[[&quot;advil&quot;,&quot;high&quot;,&quot;summaryForAdvil&quot;]]}`)
	var v restValue
	if err := json.Unmarshal(d, &amp;v); err != nil {
		panic(err)
	}
	interactions := make([]Interaction, 0, len(v.Interactions))
	for _, in := range v.Interactions {
		interactions = append(interactions, Interaction{in[0], in[1], in[2]})
	}
	drug := &amp;Drug{Name: v.Name, Dosages: v.Dosages, Interactions: interactions}
	enc := json.NewEncoder(os.Stdout)
	// if you want the whole Drug struct
	enc.Encode(drug)

	// or if you want 2 different ones:
	drug = &amp;Drug{Name: v.Name, Dosages: v.Dosages}
	enc.Encode(drug)
	for _, in := range interactions {
		enc.Encode(in)
	}
}

<kbd>playground</kbd>

huangapple
  • 本文由 发表于 2014年10月1日 10:17:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/26133129.html
匿名

发表评论

匿名网友

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

确定