I have a method which accepts an io.Reader in order to make an http POST (I can change this if needed) I will be submitted batches of x rows to this call method. I'm storing my rows as map[string]string for ease of checking that the keys are correct. What is the most streamlined way to submit a slice of map[string]string to that call method, which currently accepts a io.Reader?
Use the encoding/csv package to generate the CSV encoding. Here's how to encode to a []byte given column names:
func encodeCSV(columns []string, rows []map[string]string) ([]byte, error) {
var buf bytes.Buffer
w := csv.NewWriter(&buf)
if err := w.Write(columns); err != nil {
return nil, err
}
r := make([]string, len(columns))
for _, row := range rows {
for i, column := range columns {
r[i] = row[column]
}
if err := w.Write(r); err != nil {
return nil, err
}
}
if err := w.Flush(); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
Use bytes.NewReader to create the body for post:
data, err := encodeCSV(coluns, rows)
if err != nil {
// handle error
}
req, err := http.NewRequest("POST", url, bytes.NewReader(data))
If you have control over the data format, then consider using JSON:
data, err := json.Marshal(rows)
if err != nil {
// handle error
}
req, err := http.NewRequest("POST", url, bytes.NewReader(data))