Skip to content

Commit 51e7042

Browse files
committed
update doc and complete multipart
1 parent 5da66d1 commit 51e7042

File tree

2 files changed

+210
-13
lines changed

2 files changed

+210
-13
lines changed

content/docs/client-certificates.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ myClientCertStr := `-----BEGIN CERTIFICATE-----
2323
... cert content ...
2424
-----END CERTIFICATE-----`
2525

26-
myClientCertKeyStr := `-----BEGIN CERTIFICATE-----
26+
myClientCertKeyStr := `-----BEGIN PRIVATE KEY-----
2727
... cert key content ...
28-
-----END CERTIFICATE-----`
28+
-----END PRIVATE KEY-----`
2929

3030
client.SetCertificateFromString(myClientCertStr, myClientCertKeyStr)
3131
```

content/docs/multipart.md

Lines changed: 208 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44
Resty provides a convenient method to compose multipart form-data or ordered form-data requests.
55

66
{{% hint info %}}
7-
* Only allowed on POST, PUT, and PATCH HTTP verbs.
7+
* Only allowed on POST, PUT, and PATCH verbs.
88
* Starting v3, ordered multipart form data is possible.
99
* [Request.SetMultipartBoundary]({{% godoc v3 %}}Request.SetMultipartBoundary) setting custom boundary can be used together.
10+
* All form data and multipart methods can be used together.
1011
{{% /hint %}}
1112

12-
## Form Data
13-
1413
```go
15-
// SetMultipartBoundary(`"custom-boundary"`).
1614
res, err := c.R().
1715
SetMultipartFormData(map[string]string{
1816
"first_name": "Jeevanandam",
@@ -26,6 +24,8 @@ fmt.Println(err, res)
2624

2725
## Ordered Form Data
2826

27+
### Example 1
28+
2929
```go
3030
res, err := c.R().
3131
SetMultipartOrderedFormData("first_name", []string{"Jeevanandam"}).
@@ -34,10 +34,13 @@ res, err := c.R().
3434
Post("https://myapp.com/profile")
3535

3636
fmt.Println(err, res)
37+
```
3738

39+
### Example 2
3840

39-
// it possbile to use SetMultipartFields for ordered form-data
40-
fields := []*MultipartField{
41+
```go
42+
// it is possible to use SetMultipartFields for ordered form-data
43+
fields := []*resty.MultipartField{
4144
{
4245
Name: "field1",
4346
Values: []string{"field1value1", "field1value2"},
@@ -63,24 +66,111 @@ fmt.Println(err, res)
6366
* [Request.SetMultipartOrderedFormData]({{% godoc v3 %}}Request.SetMultipartOrderedFormData)
6467
* [Request.SetMultipartBoundary]({{% godoc v3 %}}Request.SetMultipartBoundary)
6568

69+
------------
70+
6671
# Multipart File Upload
6772

6873
{{% hint info %}}
6974
* By default, Resty streams the content in the request body when a file or `io.Reader` is detected in the MultipartField input.
70-
* Only allowed on POST, PUT, and PATCH HTTP verbs.
75+
* Only allowed on POST, PUT, and PATCH verbs.
7176
* [Request.SetMultipartBoundary]({{% godoc v3 %}}Request.SetMultipartBoundary) setting custom boundary can be used together.
77+
* All form data and multipart methods can be used together.
7278
{{% /hint %}}
7379

7480
## Upload
7581

76-
### Simple
82+
```go
83+
// add one file
84+
client.R().
85+
SetFile("my_file", "/path/to/file/sample.pdf") // field name and file path
86+
87+
// add multiple files together
88+
client.R().
89+
SetFiles(map[string]string{
90+
// field name and file path
91+
"my_file1": "/path/to/file/sample1.pdf",
92+
"my_file2": "/path/to/file/sample2.pdf",
93+
"my_file3": "/path/to/file/sample3.pdf",
94+
})
95+
```
7796

78-
### File with Content-Type
97+
### Use io.Reader
7998

80-
### Combine Form Data and Files Together
99+
```go
100+
// adding bytes or io.Reader
101+
client.R().
102+
SetFileReader(
103+
"profile_img", // field name
104+
"my-profile-img.png", // file name
105+
bytes.NewReader(profileImgBytes), // io.Reader
106+
)
107+
```
108+
109+
### With Content-Type
110+
111+
```go
112+
// adding bytes or io.Reader with file content-type
113+
client.R().
114+
SetMultipartField(
115+
"profile_img", // field name
116+
"my-profile-img.png", // file name
117+
"image/png", // file content-type
118+
bytes.NewReader(profileImgBytes), // io.Reader
119+
)
120+
```
81121

82122
## Upload Progress
83123

124+
Resty v3 provides an optional multipart live upload progress count in bytes, see
125+
* [Request.SetMultipartFields]({{% godoc v3 %}}Request.SetMultipartFields) - it is quite powerful, supports various combinations, [see example](#power-of-requestsetmultipartfields)
126+
* [MultipartField]({{% godoc v3 %}}MultipartField) input type
127+
* Refer to the godoc to know more about `Optional` fields.
128+
* [MultipartField.ProgressCallback]({{% godoc v3 %}}MultipartField) - callback method
129+
* [MultipartFieldProgress]({{% godoc v3 %}}MultipartFieldProgress) - callback method argument
130+
131+
```go
132+
progressCallback := func(mp resty.MultipartFieldProgress) {
133+
// progress argument provides all the required details
134+
fmt.Println("Name:", mp.Name)
135+
fmt.Println("FileName:", mp.FileName)
136+
fmt.Println("FileSize:", mp.FileSize)
137+
fmt.Println("Written:", mp.Written)
138+
}
139+
140+
myImageFile, _ := os.Open("/path/to/image-1.png")
141+
myImageFileStat, _ := myImageFile.Stat()
142+
143+
// demonstrate with various possibilities
144+
client.R().
145+
SetMultipartFields(
146+
[]*resty.MultipartField{
147+
// minimum required field, rest of the values are inferred
148+
// it is recommended to take advantage of input fields
149+
{
150+
Name: "myfile_1",
151+
FilePath: "/path/to/file-1.txt",
152+
ProgressCallback: progressCallback,
153+
},
154+
// with file name and content-type
155+
{
156+
Name: "myimage_1",
157+
FileName: "image-1.png",
158+
ContentType: "image/png",
159+
FilePath: "/path/to/image-1.png",
160+
ProgressCallback: progressCallback,
161+
},
162+
// with io.Reader and file size
163+
{
164+
Name: "myimage_2",
165+
FileName: "image-2.png",
166+
ContentType: "image/png",
167+
Reader: myImageFile,
168+
FileSize: myImageFileStat.Size(),
169+
ProgressCallback: progressCallback,
170+
},
171+
}...,
172+
)
173+
```
84174

85175
## Methods
86176

@@ -91,4 +181,111 @@ fmt.Println(err, res)
91181
* [Request.SetFileReader]({{% godoc v3 %}}Request.SetFileReader)
92182
* [Request.SetMultipartField]({{% godoc v3 %}}Request.SetMultipartField)
93183
* [Request.SetMultipartFields]({{% godoc v3 %}}Request.SetMultipartFields)
94-
* [Request.SetMultipartBoundary]({{% godoc v3 %}}Request.SetMultipartBoundary)
184+
* [Request.SetMultipartBoundary]({{% godoc v3 %}}Request.SetMultipartBoundary)
185+
186+
----
187+
188+
# Use Form Data and Multipart Together
189+
190+
```go
191+
// all form data and multipart methods can be used together
192+
client.R().
193+
SetFormData(map[string]string{
194+
"first_name": []string{"Jeevanandam"},
195+
}).
196+
SetFormDataFromValues(url.Values{
197+
"last_name": []string{"M"},
198+
}).
199+
SetFiles(map[string]string{
200+
// field name and file path
201+
"profile_img": "/path/to/profile/image.png",
202+
}).
203+
SetMultipartFormData(map[string]string{
204+
"zip_code": "00002",
205+
}).
206+
SetMultipartField(
207+
"profile_img2", // field name
208+
"my-profile-img2.png", // file name
209+
"image/png", // file content-type
210+
bytes.NewReader(profileImg2Bytes), // io.Reader
211+
).
212+
SetMultipartFields(
213+
&resty.MultipartField{
214+
Name: "city",
215+
Values: []string{"city name here"},
216+
},
217+
)
218+
```
219+
220+
----
221+
222+
# Power of Request.SetMultipartFields
223+
224+
* This [MultipartField]({{% godoc v3 %}}MultipartField) input has various combinations; take advantage of it as per your use case.
225+
* Refer to the godoc to know more about `Optional` fields.
226+
227+
```go
228+
myImageFile, _ := os.Open("/path/to/image-1.png")
229+
myImageFileStat, _ := myImageFile.Stat()
230+
231+
// demonstrate with various combinations and possibilities
232+
client.R().
233+
SetMultipartFields(
234+
[]*resty.MultipartField{
235+
// add form data, order is preserved
236+
{
237+
Name: "field1",
238+
Values: []string{"field1value1", "field1value2"},
239+
},
240+
{
241+
Name: "field2",
242+
Values: []string{"field2value1", "field2value2"},
243+
},
244+
// add file upload
245+
{
246+
Name: "myfile_1",
247+
FilePath: "/path/to/file-1.txt",
248+
},
249+
// add file upload with progress callback
250+
{
251+
Name: "myfile_1",
252+
FilePath: "/path/to/file-1.txt",
253+
ProgressCallback: func(mp MultipartFieldProgress) {
254+
// use the progress details
255+
},
256+
},
257+
// with file name and content-type
258+
{
259+
Name: "myimage_1",
260+
FileName: "image-1.png",
261+
ContentType: "image/png",
262+
FilePath: "/path/to/image-1.png",
263+
},
264+
// with io.Reader and file size
265+
{
266+
Name: "myimage_2",
267+
FileName: "image-2.png",
268+
ContentType: "image/png",
269+
Reader: myImageFile,
270+
FileSize: myImageFileStat.Size(),
271+
},
272+
// with io.Reader
273+
{
274+
Name: "uploadManifest1",
275+
FileName: "upload-file-1.json",
276+
ContentType: "application/json",
277+
Reader: strings.NewReader(`{"input": {"name": "Uploaded document 1", "_filename" : ["file1.txt"]}}`),
278+
},
279+
// with io.Reader and progress callback
280+
{
281+
Name: "image-file1",
282+
FileName: "image-file1.png",
283+
ContentType: "image/png",
284+
Reader: bytes.NewReader(fileBytes),
285+
ProgressCallback: func(mp MultipartFieldProgress) {
286+
// use the progress details
287+
},
288+
},
289+
}...,
290+
)
291+
```

0 commit comments

Comments
 (0)