0

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'
    },
    ...
  ]
}
2
  • 1
    json.NewDecoder().Decode is for decoding the response you got from the external service. To then pass the data along to the frontend you still need to do the json.NewEncoder().Encode. And if you want to pass the data from the external service to the frontend verbatim, i.e. without modification, you can skip the decode/encode steps and just stream the data as is. Commented Dec 8, 2022 at 4:47
  • ah! nice! wow, I got it working. you can put this as an answer to get the vote Commented Dec 8, 2022 at 4:56

1 Answer 1

1
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)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.