JSON Schema Validation in Golang

Overview

One of the important things in creating a REST API is the validation of data coming from the frontend. That is, whenever our APIs are subject to receiving data from the request body (for example) it is always good to ensure that we …


This content originally appeared on DEV Community and was authored by Francisco Mendes

Overview

One of the important things in creating a REST API is the validation of data coming from the frontend. That is, whenever our APIs are subject to receiving data from the request body (for example) it is always good to ensure that we are receiving the necessary properties and that the data types are correct.

And in golang we have some libraries that help us with this purpose and in this article we are going to use the validator library, which besides being perhaps the most popular, is the one that contains a good number of resources for us to learn on the internet.

In today's example we'll create a simple API, but then we'll proceed with implementing a middleware to validate the data before proceeding to the next handler.

Let's code

First let's install the following dependencies:

go get github.com/gofiber/fiber/v2
go get github.com/go-playground/validator/v10

Then let's create a simple API:

package main

import "github.com/gofiber/fiber/v2"

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Thank god it works 🙏")
    })

    app.Listen(":3000")
}

Now let's create a struct called Dog with the properties that we expect to come in the request body.

package main

import "github.com/gofiber/fiber/v2"

type Dog struct {
    Name      string `json:"name" validate:"required,min=3,max=12"`
    Age       int    `json:"age" validate:"required,numeric"`
    IsGoodBoy bool   `json:"isGoodBoy" validate:"required"`
}

// ...

Next we'll define the struct to standardize our error messages.

package main

import "github.com/gofiber/fiber/v2"

type Dog struct {
    Name      string `json:"name" validate:"required,min=3,max=12"`
    Age       int    `json:"age" validate:"required,numeric"`
    IsGoodBoy bool   `json:"isGoodBoy" validate:"required"`
}

type IError struct {
    Field string
    Tag   string
    Value string
}

// ...

Now we can create a new instance of the validator and we can proceed with the creation of the middleware, which I'll give the name of ValidateAddDog.

package main

import (
    "github.com/go-playground/validator/v10"
    "github.com/gofiber/fiber/v2"
)

// ...

var Validator = validator.New()

func ValidateAddDog(c *fiber.Ctx) error {
  // ...
}

// ...

Now let's validate the request body and if there was any error, the request will not go to the next handler and the errors will be sent. If there have not been any errors, the request will proceed to the next handler, like this:

package main

import (
    "github.com/go-playground/validator/v10"
    "github.com/gofiber/fiber/v2"
)

// ...

var Validator = validator.New()

func ValidateAddDog(c *fiber.Ctx) error {
    var errors []*IError
    body := new(Dog)
    c.BodyParser(&body)

    err := Validator.Struct(body)
    if err != nil {
        for _, err := range err.(validator.ValidationErrors) {
            var el IError
            el.Field = err.Field()
            el.Tag = err.Tag()
            el.Value = err.Param()
            errors = append(errors, &el)
        }
        return c.Status(fiber.StatusBadRequest).JSON(errors)
    }
    return c.Next()
}

// ...

Now let's create a new route with the POST verb that will send the data sent by the client in the response body after being validated by our middleware.

package main

import (
    "github.com/go-playground/validator/v10"
    "github.com/gofiber/fiber/v2"
)

// ...

func main() {
    // ...

    app.Post("/", ValidateAddDog, func(c *fiber.Ctx) error {
        body := new(Dog)
        c.BodyParser(&body)
        return c.Status(fiber.StatusOK).JSON(body)
    })

    app.Listen(":3000")
}

The final code should look like the following:

package main

import (
    "github.com/go-playground/validator/v10"
    "github.com/gofiber/fiber/v2"
)

type Dog struct {
    Name      string `json:"name" validate:"required,min=3,max=12"`
    Age       int    `json:"age" validate:"required,numeric"`
    IsGoodBoy bool   `json:"isGoodBoy" validate:"required"`
}

type IError struct {
    Field string
    Tag   string
    Value string
}

var Validator = validator.New()

func ValidateAddDog(c *fiber.Ctx) error {
    var errors []*IError
    body := new(Dog)
    c.BodyParser(&body)

    err := Validator.Struct(body)
    if err != nil {
        for _, err := range err.(validator.ValidationErrors) {
            var el IError
            el.Field = err.Field()
            el.Tag = err.Tag()
            el.Value = err.Param()
            errors = append(errors, &el)
        }
        return c.Status(fiber.StatusBadRequest).JSON(errors)
    }
    return c.Next()
}

func main() {
    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Thank god it works 🙏")
    })

    app.Post("/", ValidateAddDog, func(c *fiber.Ctx) error {
        body := new(Dog)
        c.BodyParser(&body)
        return c.Status(fiber.StatusOK).JSON(body)
    })

    app.Listen(":3000")
}

The end result should look like the following:

final result

Conclusion

As always, I hope you found it interesting. If you noticed any errors in this article, please mention them in the comments. 🧑🏻‍💻

Hope you have a great day! 🎄


This content originally appeared on DEV Community and was authored by Francisco Mendes


Print Share Comment Cite Upload Translate Updates
APA

Francisco Mendes | Sciencx (2021-12-26T20:53:02+00:00) JSON Schema Validation in Golang. Retrieved from https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/

MLA
" » JSON Schema Validation in Golang." Francisco Mendes | Sciencx - Sunday December 26, 2021, https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/
HARVARD
Francisco Mendes | Sciencx Sunday December 26, 2021 » JSON Schema Validation in Golang., viewed ,<https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/>
VANCOUVER
Francisco Mendes | Sciencx - » JSON Schema Validation in Golang. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/
CHICAGO
" » JSON Schema Validation in Golang." Francisco Mendes | Sciencx - Accessed . https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/
IEEE
" » JSON Schema Validation in Golang." Francisco Mendes | Sciencx [Online]. Available: https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/. [Accessed: ]
rf:citation
» JSON Schema Validation in Golang | Francisco Mendes | Sciencx | https://www.scien.cx/2021/12/26/json-schema-validation-in-golang/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.