Gin: POST request and json body

Created on 7 Sep 2015  路  13Comments  路  Source: gin-gonic/gin

hi
i try to test POST request :

package main

import (
    "fmt"

    "github.com/gin-gonic/gin"
)

type FOO struct {
    URL string `json:"url" binding:"required"`
}

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })
    r.POST("/foo", func(c *gin.Context) {
        var url FOO
        c.BindJSON(&url)
        fmt.Printf("URL to store: %v\n", url)
    })
    r.Run(":8080") // listen an
}

But i can't bind to JSON :

$ curl -i -X  POST http://localhost:8080/foo \
  -H "Accept: application/json" -H "Content-type: application/json" \
  -d '{ "url": "http://www.google.fr"聽}'
HTTP/1.1 400 Bad Request
Date: Mon, 07 Sep 2015 12:15:57 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

Any idea ? where i make an error ?
Thanks.

Most helpful comment

For anyone getting to this point and trying to figure out why their code is not working, my problem was the fact, that struct attributes were lowercase... so changing this:

type LoginCommand struct {
    username string `json:"username"`
    password string `json:"password"`
}

to this:

type LoginCommand struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

Solved the problem... Rest of the code:

v1.POST("/login", func(c *gin.Context) {
    var loginCmd LoginCommand
    c.BindJSON(&loginCmd)
    c.JSON(http.StatusOK, gin.H{"user": loginCmd.Username})
})

Not sure if that's a bug or something. This is my first day with Go lang in general :p. Maybe this will help someone to resolve their issue.

All 13 comments

Content-type should be Content-Type I guess.
Can you try the following ?

curl -i -X  POST http://localhost:8080/foo \
  -H "Accept: application/json" -H "Content-Type: application/json" \
  -d '{ "url": "http://www.google.fr" }'
$ curl -i -X  POST http://localhost:8080/foo -H "Accept: application/json" -H "Content-Type: application/json" -d '{ "url": "http://www.google.fr"聽}'
HTTP/1.1 400 Bad Request
Date: Mon, 07 Sep 2015 14:45:57 GMT
Content-Length: 0
Content-Type: text/plain; charset=utf-8

Can you add binding package import to your imports ?

package main

import (
    "fmt"
    "github.com/gin-gonic/gin/binding"
    "github.com/gin-gonic/gin"
)

i try using

"github.com/gin-gonic/gin/binding"

but i've got this error during build :

urls.go:22: imported and not used: "github.com/gin-gonic/gin/binding"

Well, I just tried doing the older version of yours (without the imports but with Content-Type). It works on my machine. Please make sure that you're at the latest version.

$ go get -u github.com/gin-gonic/gin

According to my gb manifest file i m using commit 704d690ac0e25fcd060ff82f75f913e879e65a3c

@nlamirault It's working for me as well :)

foo

@nlamirault Maybe curl was running with the environment variable $http_proxy ?
Try this one:
$ curl -i -X POST http://localhost:8080/foo \
--noproxy '*' \
-H "Accept: application/json" -H "Content-type: application/json" \
-d '{ "url": "http://www.google.fr" }'

For anyone getting to this point and trying to figure out why their code is not working, my problem was the fact, that struct attributes were lowercase... so changing this:

type LoginCommand struct {
    username string `json:"username"`
    password string `json:"password"`
}

to this:

type LoginCommand struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

Solved the problem... Rest of the code:

v1.POST("/login", func(c *gin.Context) {
    var loginCmd LoginCommand
    c.BindJSON(&loginCmd)
    c.JSON(http.StatusOK, gin.H{"user": loginCmd.Username})
})

Not sure if that's a bug or something. This is my first day with Go lang in general :p. Maybe this will help someone to resolve their issue.

@adammck Your solution worked but I am just wondering why such a thing is happening.

@blackvirus18 Now I know that it's golang standard that public members should be started with upper case, private with lowercase. That's why in the first struct username and password members where not accessible. This is in fact pretty cool idea and works fine after getting used to :D.

That's it.
public members should be started with upper case, private with lowercase

For anyone getting to this point and trying to figure out why their code is not working, my problem was the fact, that struct attributes were lowercase... so changing this:

type LoginCommand struct {
    username string `json:"username"`
    password string `json:"password"`
}

to this:

type LoginCommand struct {
    Username string `json:"username"`
    Password string `json:"password"`
}

Solved the problem... Rest of the code:

v1.POST("/login", func(c *gin.Context) {
    var loginCmd LoginCommand
    c.BindJSON(&loginCmd)
    c.JSON(http.StatusOK, gin.H{"user": loginCmd.Username})
})

Not sure if that's a bug or something. This is my first day with Go lang in general :p. Maybe this will help someone to resolve their issue.

It's not a bug. Un-exported fields can not be used for json

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ccaza picture ccaza  路  3Comments

olegsobchuk picture olegsobchuk  路  3Comments

sofish picture sofish  路  3Comments

Bloomca picture Bloomca  路  3Comments

nxvl picture nxvl  路  3Comments