NetLife Guru

Open source Go packages for fast, maintainable web systems. Built with a documentation-first approach.

Product
OverviewGolang packagesNews
Documentation
DocumentationGo LoggerGo RouterGo DB Form
Company
OverviewContactNewsGitHub
Community / Support
Supportinfo@netlife.guru
© 2026 NetLife Guru. All rights reserved.
GitHubinfo@netlife.guru
NetLife GuruNetLife GuruNetLife Guru
NetLife GuruNetLife GuruNetLife Guru
OverviewDocumentationNewsSupportContact

Golang packages

About
Optional ValidationOptional String ValidationOptional Integer ValidationOptional Float64 ValidationOptional Time ValidationOptional Pointer ValidationOptional Slice Validation
Form ValidatorOptional Validation

Optional Integer Validation

Learn how optional integer validation works in NLG Form using nullable integer fields, OptionalInt, minimum, maximum, positivity, and range validation.

OptionalInt allows integer validation rules to run only when a nullable integer value is present.

This is useful for optional counters, quantities, pagination values, priorities, limits, scoring systems, configuration values, and partial update APIs.

TL;DR

HelperDescription
optional.OptionalInt(field, rules...)Runs nested rules only when the integer pointer is non-nil
optional.MinOpt(field, n)Requires the optional value to be greater than or equal to n
optional.MinOptWithCode(field, n, code)Same as MinOpt with a custom error code
optional.MaxOpt(field, n)Requires the optional value to be less than or equal to n
optional.MaxOptWithCode(field, n, code)Same as MaxOpt with a custom error code
optional.BetweenOpt(field, min, max)Requires the optional value to be within a range
optional.BetweenOptWithCode(field, min, max, code)Same as BetweenOpt with a custom error code
optional.PositiveOpt(field)Requires the optional value to be positive
optional.PositiveOptWithCode(field, code)Same as PositiveOpt with a custom error code
optional.NegativeOpt(field)Requires the optional value to be negative
optional.NegativeOptWithCode(field, code)Same as NegativeOpt with a custom error code

Defining Optional Integer Fields

Optional integer fields use pointer values.

type OptionalIntRequest struct {
	Age      *int `json:"age"`
	Quantity *int `json:"quantity"`
	Priority *int `json:"priority"`
}

Field definitions use form.OptInt.

OptionalIntForm := struct {
	Age      form.OptIntField[OptionalIntRequest]
	Quantity form.OptIntField[OptionalIntRequest]
	Priority form.OptIntField[OptionalIntRequest]
}{
	Age: form.OptInt[OptionalIntRequest]("age", func(r *OptionalIntRequest) *int {
		return r.Age
	}),
	Quantity: form.OptInt[OptionalIntRequest]("quantity", func(r *OptionalIntRequest) *int {
		return r.Quantity
	}),
	Priority: form.OptInt[OptionalIntRequest]("priority", func(r *OptionalIntRequest) *int {
		return r.Priority
	}),
}

Applying Optional Integer Rules

return form.Schema[OptionalIntRequest]{
	optional.OptionalInt(
		OptionalIntForm.Age,
		optional.MinOpt(OptionalIntForm.Age, 18),
	),

	optional.OptionalInt(
		OptionalIntForm.Quantity,
		optional.PositiveOpt(OptionalIntForm.Quantity),
	),

	optional.OptionalInt(
		OptionalIntForm.Priority,
		optional.BetweenOpt(OptionalIntForm.Priority, 1, 10),
	),
}

Validation behavior:

InputResult
nullskipped
0validated
5valid for PositiveOpt
-1invalid for PositiveOpt

Complete Example

schema.go

package main

import (
	"github.com/netlifeguru/form"
	"github.com/netlifeguru/form/optional"
)

const (
	CodeAgeMin          = form.Code("age_min")
	CodeQuantityPositive = form.Code("quantity_positive")
	CodePriorityRange   = form.Code("priority_range")
)

type OptionalIntRequest struct {
	Age      *int `json:"age"`
	Quantity *int `json:"quantity"`
	Priority *int `json:"priority"`
}

func OptionalIntSchema() form.Schema[OptionalIntRequest] {
	OptionalIntForm := struct {
		Age      form.OptIntField[OptionalIntRequest]
		Quantity form.OptIntField[OptionalIntRequest]
		Priority form.OptIntField[OptionalIntRequest]
	}{
		Age: form.OptInt[OptionalIntRequest]("age", func(r *OptionalIntRequest) *int {
			return r.Age
		}),
		Quantity: form.OptInt[OptionalIntRequest]("quantity", func(r *OptionalIntRequest) *int {
			return r.Quantity
		}),
		Priority: form.OptInt[OptionalIntRequest]("priority", func(r *OptionalIntRequest) *int {
			return r.Priority
		}),
	}

	return form.Schema[OptionalIntRequest]{
		optional.OptionalInt(
			OptionalIntForm.Age,
			optional.MinOptWithCode(OptionalIntForm.Age, 18, CodeAgeMin),
		),

		optional.OptionalInt(
			OptionalIntForm.Quantity,
			optional.PositiveOptWithCode(OptionalIntForm.Quantity, CodeQuantityPositive),
		),

		optional.OptionalInt(
			OptionalIntForm.Priority,
			optional.BetweenOptWithCode(OptionalIntForm.Priority, 1, 10, CodePriorityRange),
		),
	}
}

main.go

package main

import (
	"encoding/json"
	"fmt"
	"log/slog"
	"net/http"
	"os"

	"github.com/netlifeguru/form"
	"github.com/netlifeguru/form/httpform"
	"github.com/netlifeguru/router"
)

func main() {
	r := router.New()

	r.HandleFunc("/optional-int", "POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		var in OptionalIntRequest

		if !httpform.BindAndValidate(w, req, &in, OptionalIntSchema(), 1<<20) {
			fmt.Println("optional integer validation failed")
			return
		}

		fmt.Println("optional integer validation passed:", in)

		w.Header().Set("Content-Type", "application/json")

		_ = json.NewEncoder(w).Encode(map[string]any{
			"message": "optional integer validation passed",
			"data":    in,
		})
	})

	validPayload := map[string]any{
		"age":      25,
		"quantity": 10,
		"priority": 5,
	}

	invalidPayload := map[string]any{
		"age":      10,
		"quantity": -1,
		"priority": 50,
	}

	skippedPayload := map[string]any{
		"age":      nil,
		"quantity": nil,
		"priority": nil,
	}

	fmt.Println("\n--- Valid request ---")
	form.SendTestPost(":8080/optional-int", validPayload)

	fmt.Println("\n--- Invalid request ---")
	form.SendTestPost(":8080/optional-int", invalidPayload)

	fmt.Println("\n--- Skipped validation request ---")
	form.SendTestPost(":8080/optional-int", skippedPayload)

	if err := r.ListenAndServe(8080); err != nil {
		slog.Error("failed to start server", "error", err)
		os.Exit(1)
	}
}

Notes

  • Optional integer validation runs only when the pointer is non-nil.
  • nil values are skipped and are not considered validation failures.
  • Optional integer fields are useful for PATCH APIs and nullable database values.
  • Use MinOpt, MaxOpt, and BetweenOpt for integer bounds validation.
  • Use PositiveOpt and NegativeOpt for intent-based numeric validation.
  • Optional integer validation remains explicit and transport-independent.
  • Custom error codes are recommended for frontend-facing APIs and public validation contracts.

Optional String Validation

Learn how optional string validation works in NLG Form using OptionalString, conditional rule execution, blank value skipping, and reusable validation pipelines.

Optional Float64 Validation

Learn how optional float64 validation works in NLG Form using nullable float fields, OptionalFloat64, minimum, maximum, and range validation.

On this page

TL;DRDefining Optional Integer FieldsApplying Optional Integer RulesComplete Exampleschema.gomain.goNotes