Basic DTO validation
This commit is contained in:
36
app/lib/helpers/validation.go
Normal file
36
app/lib/helpers/validation.go
Normal file
@ -0,0 +1,36 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
type ValidationError struct {
|
||||
ActualTag string `json:"tag"`
|
||||
Namespace string `json:"namespace"`
|
||||
Kind string `json:"kind"`
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
Param string `json:"param"`
|
||||
Field string `json:"field"`
|
||||
StructField string `json:"structField"`
|
||||
}
|
||||
|
||||
func WrapValidationErrors(errs validator.ValidationErrors) []ValidationError {
|
||||
validationErrors := make([]ValidationError, 0, len(errs))
|
||||
for _, validationErr := range errs {
|
||||
validationErrors = append(validationErrors, ValidationError{
|
||||
ActualTag: validationErr.ActualTag(),
|
||||
Namespace: validationErr.Namespace(),
|
||||
Kind: validationErr.Kind().String(),
|
||||
Type: validationErr.Type().String(),
|
||||
Value: fmt.Sprintf("%v", validationErr.Value()),
|
||||
Param: validationErr.Param(),
|
||||
Field: validationErr.Field(),
|
||||
StructField: validationErr.StructField(),
|
||||
})
|
||||
}
|
||||
|
||||
return validationErrors
|
||||
}
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/kataras/iris/v12"
|
||||
"github.com/kataras/iris/v12/middleware/accesslog"
|
||||
"github.com/kataras/iris/v12/sessions"
|
||||
@ -91,6 +92,7 @@ func createApp() *iris.Application {
|
||||
app.UseRouter(accessLog.Handler)
|
||||
app.RegisterView(iris.Jet("./app/templates", ".jet").Reload(true))
|
||||
views.CreateRouter(app)
|
||||
app.Validator = validator.New()
|
||||
|
||||
if len(cfg.Config.Application.StaticDir) > 0 {
|
||||
app.HandleDir("/static", iris.Dir(cfg.Config.Application.StaticDir))
|
||||
|
||||
@ -12,15 +12,15 @@
|
||||
<form class="mb-5 col-4 ms-auto me-auto user-edit" method="post" action="{{ .currentPath }}">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">First name</label>
|
||||
<input type="text" name="first-name" class="form-control" value="{{ .user.FirstName }}" required>
|
||||
<input type="text" name="firstName" class="form-control" value="{{ .user.FirstName }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Last name</label>
|
||||
<input type="text" name="last-name" class="form-control" value="{{ .user.LastName }}" required>
|
||||
<input type="text" name="lastName" class="form-control" value="{{ .user.LastName }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Email</label>
|
||||
<input type="email" name="email" class="form-control" value="{{ .user.Email }}" required>
|
||||
<input type="email" name="email" class="form-control" value="{{ .user.Email }}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Password</label>
|
||||
|
||||
@ -3,15 +3,17 @@ package views
|
||||
import (
|
||||
"fmt"
|
||||
"iris-test/app/lib/auth"
|
||||
"iris-test/app/lib/helpers"
|
||||
"iris-test/app/repository"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/kataras/iris/v12"
|
||||
)
|
||||
|
||||
type editUserJSON struct {
|
||||
FirstName string `json:"first-name"`
|
||||
LastName string `json:"last-name"`
|
||||
Email string `json:"email"`
|
||||
type editUserRequestDto struct {
|
||||
FirstName string `json:"firstName" validate:"required"`
|
||||
LastName string `json:"lastName" validate:"required"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
@ -20,6 +22,7 @@ func GetUsersPage(ctx iris.Context) {
|
||||
|
||||
pagination := repository.NewPagination()
|
||||
ordering := []repository.Ordering{
|
||||
repository.NewOrdering("updated_at", repository.ORDERING_DESC),
|
||||
repository.NewOrdering("first_name", repository.ORDERING_ASC),
|
||||
repository.NewOrdering("last_name", repository.ORDERING_ASC),
|
||||
}
|
||||
@ -59,11 +62,27 @@ func EditUserPage(ctx iris.Context) {
|
||||
}
|
||||
|
||||
func SaveUser(ctx iris.Context) {
|
||||
var postData editUserJSON
|
||||
var postData editUserRequestDto
|
||||
err := ctx.ReadJSON(&postData)
|
||||
|
||||
if err != nil {
|
||||
ctx.StopWithError(iris.StatusBadRequest, err)
|
||||
// Handle the error, below you will find the right way to do that...
|
||||
if errs, ok := err.(validator.ValidationErrors); ok {
|
||||
// Wrap the errors with JSON format, the underline library returns the errors as interface.
|
||||
validationErrors := helpers.WrapValidationErrors(errs)
|
||||
|
||||
// Fire an application/json+problem response and stop the handlers chain.
|
||||
ctx.StopWithProblem(
|
||||
iris.StatusBadRequest, iris.NewProblem().
|
||||
Title("Validation error").
|
||||
Detail("One or more fields failed to be validated").
|
||||
Key("errors", validationErrors).
|
||||
Key("success", false),
|
||||
)
|
||||
return
|
||||
}
|
||||
// It's probably an internal JSON error, let's dont give more info here.
|
||||
ctx.StopWithStatus(iris.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user