在Go中从REST API端点返回JSON对象。

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

return json object from REST API endpoint in Go

问题

我正在使用golang构建API。我希望这个端点返回JSON数据,以便我可以在前端中使用它。

  1. http.HandleFunc("/api/orders", createOrder)

目前我的函数没有返回JSON对象,并且jsonMap变量没有将服务器的响应体映射到CreateOrder结构体中。

我的结构体:

  1. type CreateOrder struct {
  2. Id string `json:"id"`
  3. Status string `json:"status"`
  4. Links []Links `json:"links"`
  5. }

我的createOrder函数(根据评论进行了更新):

  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. accessToken := generateAccessToken()
  3. w.Header().Set("Access-Control-Allow-Origin", "*")
  4. fmt.Println(accessToken)
  5. body := []byte(`{
  6. "intent":"CAPTURE",
  7. "purchase_units":[
  8. {
  9. "amount":{
  10. "currency_code":"USD",
  11. "value":"100.00"
  12. }
  13. }
  14. ]
  15. }`)
  16. req, err := http.NewRequest("POST", base+"/v2/checkout/orders", bytes.NewBuffer(body))
  17. req.Header.Set("Content-Type", "application/json")
  18. req.Header.Set("Authorization", "Bearer "+accessToken)
  19. client := &http.Client{}
  20. resp, err := client.Do(req)
  21. if err != nil {
  22. log.Fatalf("An Error Occured %v", err)
  23. }
  24. fmt.Println(resp.StatusCode)
  25. defer resp.Body.Close()
  26. if err != nil {
  27. log.Fatal(err)
  28. }
  29. var jsonMap CreateOrder
  30. error := json.NewDecoder(resp.Body).Decode(&jsonMap)
  31. if error != nil {
  32. log.Fatal(err)
  33. }
  34. w.WriteHeader(resp.StatusCode)
  35. json.NewEncoder(w).Encode(jsonMap)
  36. }

这是打印出来的内容。它打印出了对象的值,但没有打印出键。

  1. {2MH36251C2958825N CREATED [{something self GET} {soemthing approve GET}]}

应该打印出:

  1. {
  2. id: '8BW01204PU5017303',
  3. status: 'CREATED',
  4. links: [
  5. {
  6. href: 'url here',
  7. rel: 'self',
  8. method: 'GET'
  9. },
  10. ...
  11. ]
  12. }
英文:

I'm building the API with golang. I want this endpoint to return json data so I can use it in my frontend.

  1. http.HandleFunc("/api/orders", createOrder)

Currently my function is not returning a json object and jsonMap variable is not maping the response body to of the server with the Create struc

My struct

  1. type CreateOrder struct {
  2. Id string `json:"id"`
  3. Status string `json:"status"`
  4. Links []Links `json:"links"`
  5. }

My CreateOrder function (updated based on comments)

  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. accessToken := generateAccessToken()
  3. w.Header().Set("Access-Control-Allow-Origin", "*")
  4. fmt.Println(accessToken)
  5. body := []byte(`{
  6. "intent":"CAPTURE",
  7. "purchase_units":[
  8. {
  9. "amount":{
  10. "currency_code":"USD",
  11. "value":"100.00"
  12. }
  13. }
  14. ]
  15. }`)
  16. req, err := http.NewRequest("POST", base+"/v2/checkout/orders", bytes.NewBuffer(body))
  17. req.Header.Set("Content-Type", "application/json")
  18. req.Header.Set("Authorization", "Bearer "+accessToken)
  19. client := &http.Client{}
  20. resp, err := client.Do(req)
  21. if err != nil {
  22. log.Fatalf("An Error Occured %v", err)
  23. }
  24. fmt.Println(resp.StatusCode)
  25. defer resp.Body.Close()
  26. if err != nil {
  27. log.Fatal(err)
  28. }
  29. var jsonMap CreateOrder
  30. error := json.NewDecoder(resp.Body).Decode(&jsonMap)
  31. if error != nil {
  32. log.Fatal(err)
  33. }
  34. w.WriteHeader(resp.StatusCode)
  35. json.NewEncoder(w).Encode(jsonMap)
  36. }

This is what gets printed. Prints the value without the keys of the object

  1. {2MH36251C2958825N CREATED [{something self GET} {soemthing approve GET}]}

Should print

  1. {
  2. id: '8BW01204PU5017303',
  3. status: 'CREATED',
  4. links: [
  5. {
  6. href: 'url here',
  7. rel: 'self',
  8. method: 'GET'
  9. },
  10. ...
  11. ]
  12. }

答案1

得分: 1

  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. resp, err := http.DefaultClient.Do(req)
  4. if err != nil {
  5. log.Println("发生错误:", err)
  6. return
  7. }
  8. defer resp.Body.Close()
  9. if resp.StatusCode != http.StatusOK /* 或者 http.StatusCreated(取决于你使用的API) */ {
  10. log.Println("请求失败,状态为:", http.Status)
  11. w.WriteHeader(resp.StatusCode)
  12. return
  13. }
  14. // 解码来自外部服务的响应
  15. v := new(CreateOrder)
  16. if err := json.NewDecoder(resp.Body).Decode(v); err != nil {
  17. log.Println(err)
  18. return
  19. }
  20. // 发送响应到前端
  21. w.WriteHeader(resp.StatusCode)
  22. if err := json.NewEncoder(w).Encode(v); err != nil {
  23. log.Println(err)
  24. }
  25. }

或者,如果你想将来自外部服务的数据原样发送到前端,你可以像这样做:

  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. resp, err := http.DefaultClient.Do(req)
  4. if err != nil {
  5. log.Println("发生错误:", err)
  6. return
  7. }
  8. defer resp.Body.Close()
  9. if resp.StatusCode != http.StatusOK /* 或者 http.StatusCreated(取决于你使用的API) */ {
  10. log.Println("请求失败,状态为:", http.Status)
  11. w.WriteHeader(resp.StatusCode)
  12. return
  13. }
  14. // 将外部服务的响应复制到前端
  15. w.WriteHeader(resp.StatusCode)
  16. if _, err := io.Copy(w, resp.Body); err != nil {
  17. log.Println(err)
  18. }
  19. }
英文:
  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. resp, err := http.DefaultClient.Do(req)
  4. if err != nil {
  5. log.Println("An Error Occured:", err)
  6. return
  7. }
  8. defer resp.Body.Close()
  9. if resp.StatusCode != http.StatusOK /* or http.StatusCreated (depends on the API you're using) */ {
  10. log.Println("request failed with status:", http.Status)
  11. w.WriteHeader(resp.StatusCode)
  12. return
  13. }
  14. // decode response from external service
  15. v := new(CreateOrder)
  16. if err := json.NewDecoder(resp.Body).Decode(v); err != nil {
  17. log.Println(err)
  18. return
  19. }
  20. // send response to frontend
  21. w.WriteHeader(resp.StatusCode)
  22. if err := json.NewEncoder(w).Encode(v); err != nil {
  23. log.Println(err)
  24. }
  25. }

Alternatively, if you want to send the data from the external service to the frontend unchanged, you should be able to do something like this:

  1. func createOrder(w http.ResponseWriter, r *http.Request) {
  2. // ...
  3. resp, err := http.DefaultClient.Do(req)
  4. if err != nil {
  5. log.Println("An Error Occured:", err)
  6. return
  7. }
  8. defer resp.Body.Close()
  9. if resp.StatusCode != http.StatusOK /* or http.StatusCreated (depends on the API you're using) */ {
  10. log.Println("request failed with status:", http.Status)
  11. w.WriteHeader(resp.StatusCode)
  12. return
  13. }
  14. // copy response from external to frontend
  15. w.WriteHeader(resp.StatusCode)
  16. if _, err := io.Copy(w, resp.Body); err != nil {
  17. log.Println(err)
  18. }
  19. }

huangapple
  • 本文由 发表于 2022年12月8日 12:09:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/74725422.html
匿名

发表评论

匿名网友

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

确定