在使用Gorilla的Go ReST服务中操作JSON

时间:2014-10-01 02:17:40

标签: json rest go

我有一个接收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) {

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

我的目标是在CreateDrug函数中创建两个不同的JSON,因此我可以创建两个不同的结构,药物和交互:

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

在Go中,在此函数中,如何使用收到的JSON创建两个新的JSON?

2 个答案:

答案 0 :(得分:0)

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

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.
}

Playground link

(我假设你想要填充Interactions字段的Drug的单个JSON值。如果那不是你想要的,分别编组药物和相互作用的值。)

答案 1 :(得分: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)
    // if you want the whole Drug struct
    enc.Encode(drug)

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

playground