I am working on creating a custom terraform provider by using terraform sdk. I am trying to read data from the existing API GET call. I am finding it difficult to map the JSON response from an API to terraform schema. This is my data source schema:
func dataSourceProjects() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceProjectsRead,
Schema: map[string]*schema.Schema{
"members": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
"owners": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Computed: true,
},
},
}
}
This is the API JSON response:
{
"members": [
"test12",
"test8800",
"test0032",
"test1234",
],
"owners": [
"test000",
"test111",
"test12",
"test1234",
]
}
This is my Data source read function
func dataSourceProjectsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := &http.Client{Timeout: 10 * time.Second}
// Warning or errors can be collected in a slice type
var diags diag.Diagnostics
req, err := http.NewRequest("GET", fmt.Sprintf("%s/test/team", "https://myurl/v1"), nil)
req.Header.Add("Authorization", "Bearer xxxxx")
if err != nil {
return diag.FromErr(err)
}
r, err := client.Do(req)
if err != nil {
return diag.FromErr(err)
}
defer r.Body.Close()
members := make([]string, 0)
err = json.NewDecoder(r.Body).Decode(&members)
if err != nil {
return diag.FromErr(err)
}
if err := d.Set("members", members); err != nil {
return diag.FromErr(err)
}
// always run
d.SetId(strconv.FormatInt(time.Now().Unix(), 10))
return diags
}
I keep getting this error:
Error: json: cannot unmarshal object into Go value of type []string
CodePudding user response:
I believe you need to unmarshal to a type matching the format of your JSON instead of attempting to somehow implicitly transform it into a string slice:
members := make(map[string][]string)
err = json.NewDecoder(r.Body).Decode(&members)
CodePudding user response:
Not sure if you pasted the correct API output or not but it is incorrect json since it contain extra ,
before closing square brackets ]
{
"members": [
"test12",
"test8800",
"test0032",
"test1234", <- extra comma
],
"owners": [
"test000",
"test111",
"test12",
"test1234", <- extra comma
]
}
Below quotes work after removing the extra comma ,
package main
import (
"encoding/json"
"fmt"
"log"
"strings"
)
func main() {
const jsonStream = `{
"members": [
"test12",
"test8800",
"test0032",
"test1234"
],
"owners": [
"test000",
"test111",
"test12",
"test1234"
]
}
`
dec := json.NewDecoder(strings.NewReader(jsonStream))
var m map[string][]string
err := dec.Decode(&m)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%T: %v\n", m, m)
}
Note: If still the above code doesn't work then check to make sure the response Body
is as posted, or you can try with interface and check the structure for testing.