Golang : gin tutorial - 3 (Create a POST request)

·

2 min read

Golang : gin tutorial - 3 (Create a POST request)

In the previous article we created a GET endpoint using golang's gin framework. In this article we are going to see how to create a POST request endpoint golang's gin http framework.

Step 1

Create a struct called content in a file model.go in the content directory as most POST request accepts a request body.

package content

type content struct {
    Id   string `json:"id" binding:"required"`
    Name string `json:"name" binding:"required"`
}

Step 2

Create an endpoint in the controller.go file which can accept accept a request body as most POST request do. As shown below gin context is used to bing the request body json to a struct and if the binding throws any error then we just return a 400 i.e, Bad Request error as http status.

func PostContents(ctx *gin.Context) {
    var content content
    if err := ctx.ShouldBindJSON(&content); err != nil {
        ctx.Error(err)
        ctx.AbortWithStatus(http.StatusBadRequest)
        return
    }
    ctx.JSON(http.StatusOK, content)
}

Step 3

Register the above created POST endpoint in a similar way we registered the GET endpoint in the main.go file as we did before.

v1 := engine.Group("/api/v1")
{
    v1.GET("/contents", content.GetContents)
    v1.POST("/contents", content.PostContents)
}

Step 4

Write unit tests for the POST endpoint. There are 2 tests shown below which show both success and failure tests of the POST request with and without the required request body.

func TestPostContents_success(t *testing.T) {
    responseRecorder := httptest.NewRecorder()
    ctx, engine := gin.CreateTestContext(responseRecorder)
    engine.POST("/contents", PostContents)
    requestBody := `{"id":"some-random-id","name":"content name"}`
    ctx.Request = httptest.NewRequest(http.MethodPost, "/contents", bytes.NewBuffer([]byte(requestBody)))
    engine.ServeHTTP(responseRecorder, ctx.Request)

    assert.Equal(t, http.StatusOK, responseRecorder.Code)
    assert.Equal(t, requestBody, responseRecorder.Body.String())
}

func TestPostContents_failure(t *testing.T) {
    responseRecorder := httptest.NewRecorder()
    ctx, engine := gin.CreateTestContext(responseRecorder)
    engine.POST("/contents", PostContents)
    ctx.Request = httptest.NewRequest(http.MethodPost, "/contents", nil)
    engine.ServeHTTP(responseRecorder, ctx.Request)

    assert.Equal(t, http.StatusBadRequest, responseRecorder.Code)
}

Step 5

Now, run the application and access the POST endpoint http://localhost:8080/api/v1/contents with the request body to see the same in the response.

{
    "id":"some-random-id",
    "name":"content name"
}

Did you find this article valuable?

Support Deepak by becoming a sponsor. Any amount is appreciated!