-2

All examples of working with JSON describe how to serialize to JSON simple or user types (like a struct).

But I have a different case: a) I don't know the fields of my type/object b) every object will have different types.

Here is my case in pseudocode:

while `select * from item` do
  while `select fieldname, fieldvalue from fields where fields.itemid = item.id` do
    ...

For each entity in my database I get field names and field values. In the result I need to get something like this:

{
  "item.field1": value,
  ...
  "item.fieldN": value,
  "custom_fields": {
     "fields.field1": value,
      ...
     "fields.fieldK": value
  }
}

What is the best way to do it in Go? Is there any useful libraries or functions in standard library ?

Update: The source of data is the database. In the result i need to get JSON as string to POST it to external web service. So, the program just read data from database and make POST requests to REST service.

ceth
  • 44,198
  • 62
  • 180
  • 289
  • I think you can achieve this with a custom marshaler. I don't think Go has the ability to do this built into it by default, you will have to write your own logic. The `encoding/json` package allows a custom marshaller on your structs. Take a look [here](https://golang.org/pkg/encoding/json/#example__customMarshalJSON). – Lansana Camara Aug 07 '17 at 12:44
  • 1
    Take a look at [https://stackoverflow.com/questions/40559250/golang-dynamic-creating-member-of-struct/40568896](https://stackoverflow.com/questions/40559250/golang-dynamic-creating-member-of-struct/40568896#40568896). The example is for `Unmarshal` but the idea is the same, i.e. save your object to `map[string]interface{}` then use `json.Marshal` to serialize the object to JSON. – putu Aug 07 '17 at 12:58

1 Answers1

1

What exactly is your target type supposed to be? It can't be a struct since you do not know the fields beforehand.

The only fitting type to me seems to be a map of type map[string]interface{}: with it any nested structure can be achieved:

a := map[string]interface{}{
    "item.field1": "val1",
    "item.field2": "val2",
    "item.fieldN": "valN",
    "custom_fields": map[string]interface{}{
        "fields.field1": "cval1",
        "fields.field2": "cval2",
    },
}
b, err := json.Marshal(a)

See playground sample here.

Filling this structure from a database as you hinted at should probably be a custom script (not using json).

Note: custom_fields can also be of other types depending on what type the value column is in the database. If the value column is a string use map[string]string.

TehSphinX
  • 6,536
  • 1
  • 24
  • 34
  • >> What exactly is your target type supposed to be? I don't need a type. I need json as string to POST it to external web service. Thanks. – ceth Aug 07 '17 at 13:05
  • you always have a type and if it is `interface{}`. You question is not quite clear on this. Your target seems to be string but what is your source? – TehSphinX Aug 07 '17 at 13:07
  • The source is the database. I need to read a data from database and make POST requests to REST server. – ceth Aug 07 '17 at 13:08
  • 1
    Thanks. Looks like your answer is what I need. I will create map dynamically and next serialize it to JSON like in your code. – ceth Aug 07 '17 at 13:19