Skip to content

Commit 8942f49

Browse files
joeybloggsjoeybloggs
authored andcommitted
Add Decode() to the Context object for JSON, XML, FORM + Multipart FORM decoding into a struct.
- used new library from github.com/go-playground/form
1 parent a033ad7 commit 8942f49

File tree

6 files changed

+99
-8
lines changed

6 files changed

+99
-8
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
##LARS
22
<img align="right" src="https://raw.githubusercontent.com/go-playground/lars/master/examples/README/test.gif">
3-
![Project status](https://img.shields.io/badge/version-3.0-green.svg)
3+
![Project status](https://img.shields.io/badge/version-3.1-green.svg)
44
[![Build Status](https://semaphoreci.com/api/v1/projects/4351aa2d-2f94-40be-a6ef-85c248490378/679708/badge.svg)](https://semaphoreci.com/joeybloggs/lars)
55
[![Coverage Status](https://coveralls.io/repos/github/go-playground/lars/badge.svg?branch=master)](https://coveralls.io/github/go-playground/lars?branch=master)
66
[![Go Report Card](https://goreportcard.com/badge/go-playground/lars)](https://goreportcard.com/report/go-playground/lars)
@@ -179,6 +179,19 @@ func Home(c *MyContext) {
179179
}
180180
```
181181

182+
Decoding Body
183+
-------------
184+
For full example see [here](https://github.com/go-playground/lars/blob/master/examples/decode/main.go).
185+
currently JSON, XML, FORM + Multipart Form's are support out of the box.
186+
```go
187+
// first argument denotes yes or no I would like URL query parameter fields
188+
// to be included. i.e. 'id' in route '/user/:id' should it be included.
189+
// run, then change to false and you'll see user.ID is not populated.
190+
if err := c.Decode(true, maxBytes, &user); err != nil {
191+
log.Println(err)
192+
}
193+
```
194+
182195
Misc
183196
-----
184197
```go

context.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"strings"
1010
"time"
1111

12-
"github.com/go-playground/form"
1312
"github.com/gorilla/websocket"
1413
"golang.org/x/net/context"
1514
)
@@ -416,15 +415,13 @@ func (c *Ctx) Inline(r io.Reader, filename string) (err error) {
416415
return
417416
}
418417

419-
// Decode takes the request and attempts to discover it's type
420-
// via http headers and then unmarshal into the provided struct.
421-
// Example if header was "application/json" would unmarshal using
418+
// Decode takes the request and attempts to discover it's content type via
419+
// the http headers and then decode the request body into the provided struct.
420+
// Example if header was "application/json" would decode using
422421
// json.NewDecoder(io.LimitReader(c.request.Body, maxMemory)).Decode(v).
423422
func (c *Ctx) Decode(includeFormQueryParams bool, maxMemory int64, v interface{}) (err error) {
424423

425-
c.l.formDecoderInit.Do(func() {
426-
c.l.formDecoder = form.NewDecoder()
427-
})
424+
c.l.initFormDecoder()
428425

429426
typ := c.request.Header.Get(ContentType)
430427

context_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func TestDecode(t *testing.T) {
4949
err := c.Decode(false, 16<<10, test)
5050
Equal(t, err, nil)
5151
})
52+
53+
NotEqual(t, l.BuiltInFormDecoder(), nil)
54+
5255
hf := l.Serve()
5356

5457
form := url.Values{}

doc.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ example context + custom handlers
152152
...
153153
}
154154
155+
Decoding Body
156+
157+
For full example see https://github.com/go-playground/lars/blob/master/examples/decode/main.go
158+
currently JSON, XML, FORM + Multipart Form's are support out of the box.
159+
160+
// first argument denotes yes or no I would like URL query parameter fields
161+
// to be included. i.e. 'id' in route '/user/:id' should it be included.
162+
// run, then change to false and you'll see user.ID is not populated.
163+
if err := c.Decode(true, maxBytes, &user); err != nil {
164+
log.Println(err)
165+
}
166+
167+
155168
Misc
156169
157170
misc examples and noteworthy features

examples/decode/main.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"net/url"
7+
"time"
8+
9+
"github.com/go-playground/lars"
10+
)
11+
12+
const (
13+
// used for io.LimitReader(...) for safetly!
14+
maxBytes = 16 << 10
15+
)
16+
17+
// User ...
18+
type User struct {
19+
ID int `form:"id"`
20+
Name string
21+
}
22+
23+
func main() {
24+
25+
l := lars.New()
26+
l.Post("/user/:id", PostUser)
27+
28+
go simulateFormPost()
29+
30+
http.ListenAndServe(":3007", l.Serve())
31+
}
32+
33+
// PostUser ...
34+
func PostUser(c lars.Context) {
35+
var user User
36+
37+
// first argument denotes yes or no I would like URL query parameter fields
38+
// to be included. i.e. 'id' in route '/user/:id' should it be included.
39+
// run, then change to false and you'll see user.ID is not populated.
40+
if err := c.Decode(true, maxBytes, &user); err != nil {
41+
log.Println(err)
42+
}
43+
44+
log.Printf("%#v", user)
45+
}
46+
47+
func simulateFormPost() {
48+
time.Sleep(1000)
49+
http.PostForm("http://localhost:3007/user/13", url.Values{"Name": {"joeybloggs"}})
50+
}

lars.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,21 @@ func New() *LARS {
213213
return l
214214
}
215215

216+
// BuiltInFormDecoder returns the built in form decoder github.com/go-playground/form
217+
// in order for custom type to be registered.
218+
func (l *LARS) BuiltInFormDecoder() *form.Decoder {
219+
220+
l.initFormDecoder()
221+
222+
return l.formDecoder
223+
}
224+
225+
func (l *LARS) initFormDecoder() {
226+
l.formDecoderInit.Do(func() {
227+
l.formDecoder = form.NewDecoder()
228+
})
229+
}
230+
216231
// RegisterCustomHandler registers a custom handler that gets wrapped by HandlerFunc
217232
func (l *LARS) RegisterCustomHandler(customType interface{}, fn CustomHandlerFunc) {
218233

0 commit comments

Comments
 (0)