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 String Validation

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

OptionalString allows string validation rules to run only when the string contains a meaningful value.

This makes it possible to validate optional text input without forcing users to provide the field.

It is especially useful for:

  • profile updates
  • PATCH APIs
  • optional descriptions
  • nicknames
  • social links
  • optional metadata
  • partial onboarding
  • admin forms
  • settings pages

Validation Philosophy

Unlike required validation, optional validation skips nested rules entirely when the value is considered empty.

This allows schemas to naturally support optional fields without additional conditional logic.

Example:

optional.OptionalString(
	UserForm.Nickname,
	rules.MinLen(UserForm.Nickname, 3),
)

Validation behavior:

InputResult
""skipped
" "skipped
"ab"invalid
"john"valid

TL;DR

HelperDescription
optional.OptionalString(field, rules...)Runs nested rules only when the string is non-empty
optional.OptionalStringTrim(field, rules...)Trims whitespace before evaluating emptiness
optional.OptionalStringWith(field, fn)Runs custom conditional string validation
optional.OptionalStringValue(field, value, rules...)Runs rules only when the string equals a specific value

Defining Optional String Fields

Optional string validation starts with regular string field definitions.

OptionalForm := struct {
	Nickname form.StringField[OptionalStringRequest]
	Bio      form.StringField[OptionalStringRequest]
	Email    form.StringField[OptionalStringRequest]
}{
	Nickname: form.Str[OptionalStringRequest]("nickname", func(r *OptionalStringRequest) string {
		return r.Nickname
	}),
	Bio: form.Str[OptionalStringRequest]("bio", func(r *OptionalStringRequest) string {
		return r.Bio
	}),
	Email: form.Str[OptionalStringRequest]("email", func(r *OptionalStringRequest) string {
		return r.Email
	}),
}

Optional validation wraps normal validation rules.

OptionalString

OptionalString skips nested validation rules when the string is blank.

Example:

optional.OptionalString(
	OptionalForm.Nickname,
	rules.MinLen(OptionalForm.Nickname, 3),
)

Validation flow:

empty string
    ↓
validation skipped
non-empty string
    ↓
nested rules executed

Typical use cases:

  • optional nicknames
  • optional profile fields
  • optional labels
  • optional comments

OptionalStringTrim

OptionalStringTrim trims whitespace before checking whether the value is empty.

Example:

optional.OptionalStringTrim(
	OptionalForm.Bio,
	rules.MaxLen(OptionalForm.Bio, 200),
)

Validation behavior:

InputResult
""skipped
" "skipped
"hello"validated

This is useful for frontend form input where users may accidentally submit whitespace-only values.

OptionalStringWith

OptionalStringWith allows fully custom conditional validation logic.

Example:

optional.OptionalStringWith(
	OptionalForm.Email,
	func(v string) bool {
		return strings.Contains(v, "@company.com")
	},
	rules.Email(OptionalForm.Email),
)

This helper is useful for:

  • feature-flagged validation
  • domain-restricted input
  • custom conditional validation flows
  • advanced business rules

OptionalStringValue

OptionalStringValue only executes validation rules when the string matches a specific value.

Example:

optional.OptionalStringValue(
	OptionalForm.Type,
	"business",
	rules.Required(OptionalForm.CompanyName),
)

Typical use cases:

  • conditional form sections
  • account type validation
  • business onboarding flows
  • feature-dependent validation

Combining Optional Rules

Optional validation can wrap multiple validation rules.

Example:

optional.OptionalString(
	OptionalForm.Nickname,
	rules.MinLen(OptionalForm.Nickname, 3),
	rules.MaxLen(OptionalForm.Nickname, 20),
	rules.Regex(OptionalForm.Nickname, nicknameRegex),
)

This creates reusable optional validation pipelines.

Complete Example

schema.go

package main

import (
	"regexp"

	"github.com/netlifeguru/form"
	"github.com/netlifeguru/form/optional"
	"github.com/netlifeguru/form/rules"
)

const (
	CodeNicknameMinLen = form.Code("nickname_min_len")
	CodeBioMaxLen      = form.Code("bio_max_len")
	CodeSlugRegex      = form.Code("slug_regex")
)

type OptionalStringRequest struct {
	Nickname string `json:"nickname"`
	Bio      string `json:"bio"`
	Email    string `json:"email"`
	Slug     string `json:"slug"`
}

func OptionalStringSchema() form.Schema[OptionalStringRequest] {
	OptionalForm := struct {
		Nickname form.StringField[OptionalStringRequest]
		Bio      form.StringField[OptionalStringRequest]
		Email    form.StringField[OptionalStringRequest]
		Slug     form.StringField[OptionalStringRequest]
	}{
		Nickname: form.Str[OptionalStringRequest]("nickname", func(r *OptionalStringRequest) string {
			return r.Nickname
		}),
		Bio: form.Str[OptionalStringRequest]("bio", func(r *OptionalStringRequest) string {
			return r.Bio
		}),
		Email: form.Str[OptionalStringRequest]("email", func(r *OptionalStringRequest) string {
			return r.Email
		}),
		Slug: form.Str[OptionalStringRequest]("slug", func(r *OptionalStringRequest) string {
			return r.Slug
		}),
	}

	slugRegex := regexp.MustCompile(`^[a-z0-9-]+$`)

	return form.Schema[OptionalStringRequest]{
		optional.OptionalString(
			OptionalForm.Nickname,
			rules.MinLenWithCode(OptionalForm.Nickname, 3, CodeNicknameMinLen),
		),

		optional.OptionalStringTrim(
			OptionalForm.Bio,
			rules.MaxLenWithCode(OptionalForm.Bio, 20, CodeBioMaxLen),
		),

		optional.OptionalString(
			OptionalForm.Email,
			rules.Email(OptionalForm.Email),
		),

		optional.OptionalString(
			OptionalForm.Slug,
			rules.RegexWithCode(OptionalForm.Slug, slugRegex, CodeSlugRegex),
		),
	}
}

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-string", "POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		var in OptionalStringRequest

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

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

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

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

	validPayload := map[string]any{
		"nickname": "john",
		"bio":      "short bio",
		"email":    "john@example.com",
		"slug":     "hello-world",
	}

	invalidPayload := map[string]any{
		"nickname": "ab",
		"bio":      "this bio is definitely too long",
		"email":    "invalid-email",
		"slug":     "Hello World!",
	}

	skippedPayload := map[string]any{
		"nickname": "",
		"bio":      "",
		"email":    "",
		"slug":     "",
	}

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

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

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

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

Notes

  • Optional validation skips nested rules when the string is blank.
  • OptionalStringTrim treats whitespace-only values as empty.
  • Optional validation is useful for PATCH APIs and partial updates.
  • Optional validation can wrap any regular string validation rule.
  • Optional validation keeps schemas reusable and transport-independent.
  • Empty values are skipped intentionally and are not considered validation failures.
  • Optional validation is composable and works naturally with conditional validation pipelines.

Optional Validation

Learn how optional validation works in NLG Form using OptionalString, OptionalPtr, OptionalSlice, nullable fields, and conditional validation pipelines.

Optional Integer Validation

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

On this page

Validation PhilosophyTL;DRDefining Optional String FieldsOptionalStringOptionalStringTrimOptionalStringWithOptionalStringValueCombining Optional RulesComplete Exampleschema.gomain.goNotes