Home > Software design >  return json object from REST API endpoint in Go
return json object from REST API endpoint in Go

Time:12-08

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

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

type CreateOrder struct {
    Id     string  `json:"id"`
    Status string  `json:"status"`
    Links  []Links `json:"links"`
}

My CreateOrder function (updated based on comments)

func createOrder(w http.ResponseWriter, r *http.Request) {
    accessToken := generateAccessToken()
    w.Header().Set("Access-Control-Allow-Origin", "*")
    fmt.Println(accessToken)

    body := []byte(`{
        "intent":"CAPTURE",
        "purchase_units":[
           {
              "amount":{
                 "currency_code":"USD",
                 "value":"100.00"
              }
           }
        ]
     }`)

    req, err := http.NewRequest("POST", base "/v2/checkout/orders", bytes.NewBuffer(body))
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Authorization", "Bearer " accessToken)

    client := &http.Client{}
    resp, err := client.Do(req)

    if err != nil {
        log.Fatalf("An Error Occured %v", err)
    }

    fmt.Println(resp.StatusCode)
    defer resp.Body.Close()

    if err != nil {
        log.Fatal(err)
    }

    var jsonMap CreateOrder

    error := json.NewDecoder(resp.Body).Decode(&jsonMap)

    if error != nil {
        log.Fatal(err)
    }

    w.WriteHeader(resp.StatusCode)
    json.NewEncoder(w).Encode(jsonMap)

}

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

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

Should print

{
  id: '8BW01204PU5017303',
  status: 'CREATED',
  links: [
    {
      href: 'url here',
      rel: 'self',
      method: 'GET'
    },
    ...
  ]
}

CodePudding user response:

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

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Println("An Error Occured:", err)
        return
    }
    defer resp.Body.Close()
    
    if resp.StatusCode != http.StatusOK /* or http.StatusCreated (depends on the API you're using) */ {
        log.Println("request failed with status:", http.Status)
        w.WriteHeader(resp.StatusCode)
        return
    }

    // decode response from external service
    v := new(CreateOrder)
    if err := json.NewDecoder(resp.Body).Decode(v); err != nil {
        log.Println(err)
        return
    }
    
    // send response to frontend
    w.WriteHeader(resp.StatusCode)
    if err := json.NewEncoder(w).Encode(v); err != nil {
        log.Println(err)
    }
}

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:

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

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Println("An Error Occured:", err)
        return
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK /* or http.StatusCreated (depends on the API you're using) */ {
        log.Println("request failed with status:", http.Status)
        w.WriteHeader(resp.StatusCode)
        return
    }

    // copy response from external to frontend
    w.WriteHeader(resp.StatusCode)
    if _, err := io.Copy(w, resp.Body); err != nil {
        log.Println(err)
    }
}

CodePudding user response:

You need to encode the response body to a JSON format in order to return it.

json.NewEncoder(w).Encode(jsonMap)
  • Related