resty
resty copied to clipboard
Is there anyway to make multipart formdata has order?
I am working with graphql-upload and it's processor must accept one field before any other fields, otherwise it will throw an error. I know that map has no order and should has no order, but if there is anyway to make a raw body of multipart and keep its order?
Find myself a workaround, use mime/multipart
to create body, set raw body and content-type will keep the order.
var bBody bytes.Buffer
writer := multipart.NewWriter(&bBody)
writer.WriteField("firstkey","firstvalue")
writer.WriteField("secondkey","secondvalue")
part, err := writer.CreateFormFile("fieldname", "filename")
if err != nil {
return nil, err
}
part.Write([]byte("filecontent"))
writer.Close()
request := c.Client.R()
request.SetHeader("Content-Type", writer.FormDataContentType())
request.SetBody(bBody.Bytes())
resp, err := request.Post("endpoint")
@Sczlog Thanks for bringing it up and finding a workaround to move forward. I may think of a way to preserve order.
Can we add a new method that can accept a slice instead of map and write it to the body in the same order ?
My rant: Go insists that maps don't/can't have order. But that's an implementation issue based on the fact that these are Hash based maps instead of Tree based maps (which are ordered).
What might be a slightly better solution than a slice (just a consideration) - take a sort function. Then it can be by insertion order or actual sort order.
I don't know what the spec for mime/multipart
says, but definitely don't deviate from it.
@chb0github I hear you! I will have to check the RFC spec for this part.
A possible workaround/approach (as @praem90 mentioned above) is to add a method to accept the slice and process it.
I am working with graphql-upload and it's processor must accept one field before any other fields, otherwise it will throw an error. I know that map has no order and should has no order, but if there is anyway to make a raw body of multipart and keep its order?
this can help you:
package main
import (
"log"
"strings"
"github.com/gospider007/requests"
)
func main() {
orderMap := requests.NewOrderMap()
orderMap.Set("name", "test")
orderMap.Set("age", 11)
orderMap.Set("sex", "boy")
resp, err := requests.Post(nil, "https://httpbin.org/anything", requests.RequestOption{
Form: orderMap,
})
if err != nil {
log.Panic(err)
}
jsonData, err := resp.Json()
if err != nil {
log.Panic(err)
}
if !strings.HasPrefix(jsonData.Get("headers.Content-Type").String(), "multipart/form-data") {
log.Panic("json data error")
}
if jsonData.Get("form.name").String() != "test" {
log.Panic("json data error")
}
}