18

I'm using Echo to build a minimalist server in Golang.

In, Echo one can bind an incoming JSON request payload to a struct internally and access the payload.

However I have a scenario wherein I know only 3 fields of the incoming JSON request payload, and the bind doesn't work in this case.

How do I still access the 3 fields that I care about ? If I cannot do this in Echo, can you recommend me a JSON decoder that works with Echo's context structure?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
7hacker
  • 1,928
  • 3
  • 19
  • 32
  • I do not know Echo, but in most languages that have bindings like this, if you do not know the whole object, you have to resort to parsing the JSON with a lower level library. – nycynik Dec 31 '16 at 18:13
  • 1
    I have no problems doing this. Mind posting some of your code? – noisypixy Dec 31 '16 at 18:23

5 Answers5

20

This is how I did it:

json_map := make(map[string]interface{})
err := json.NewDecoder(c.Request().Body).Decode(&json_map)
if err != nil {
    return err
} else {
    //json_map has the JSON Payload decoded into a map
    cb_type := json_map["type"]
    challenge := json_map["challenge"]
7hacker
  • 1,928
  • 3
  • 19
  • 32
3

I created a custom function that retrieves raw json body and returns a nil if no values present otherwise in returns a map[string]interface{}

import (
   "encoding/json"
   "github.com/labstack/echo/v4"
   "github.com/labstack/gommon/log"
)
 
 
func GetJSONRawBody(c echo.Context) map[string]interface{}  {

     jsonBody := make(map[string]interface{})
     err := json.NewDecoder(c.Request().Body).Decode(&jsonBody)
     if err != nil {

         log.Error("empty json body")
         return nil
     }

    return jsonBody
}
philip mudenyo
  • 714
  • 8
  • 8
2

I'm not the most experienced with Echo, but to my knowledge the bind won't work in this case. @elithar provided what may be a good answer to your question in another thread:


From: Golang Json single value parsing

You can decode into a map[string]interface{} and then get the element by key.

data := make(map[string]interface{})
err := json.Unmarshal(content, &data)
if err != nil {
   return nil, err
}

price, ok := data["ask_price"].(string); !ok {
    // ask_price is not a string
    return nil, errors.New("wrong type")
}

// Use price as you wish

Structs are often preferred as they are more explicit about the type. You only have to declare the fields in the JSON you care about, and you don't need to type assert the values as you would with a map (encoding/json handles that implicitly).


You should be able to grab your context's data and extract the fields you want in this manner.

Community
  • 1
  • 1
Dan 0
  • 914
  • 7
  • 15
1

Using Golang's Echo framework, you extract data from JSON like this

Sample Json

{
    "username": "Super User",
    "useremail": "super@user.email"
}

Code


import (
    "github.com/labstack/echo"
)

func main() {
    my_data := echo.Map{}
    if err := echoCtx.Bind(&my_data); err != nil {
        return err
    } else {

        username := fmt.Sprintf("%v", my_data["username"])
        useremail := fmt.Sprintf("%v", my_data["useremail"])
    }
}
Muhammad Tariq
  • 3,318
  • 5
  • 38
  • 42
0

here is the simple solution

func UnwantedJSONHandler(c echo.Context){
    b, _ := io.ReadAll(c.Request().Body)
    var r RequestDataAssumedStruct
    if err := json.Unmarshal(b, &r); err != nil {
        log.Println(err.Error())
        return err
    }
    log.Println(r)
}

We just took the byte data from the request body and unmarshaled the JSON. I have seen some solution given by the others but it seems that's a log way so i still put the answer even though it is marked as solved

Smit shah
  • 35
  • 8