package api
import "strings"
type Issue struct {
Field string `json:"field"`
Message string `json:"message"`
}
type CreateReq struct {
Name string `json:"name"`
Email string `json:"email"`
}
func (r CreateReq) Validate() []Issue {
issues := make([]Issue, 0)
if strings.TrimSpace(r.Name) == "" {
issues = append(issues, Issue{Field: "name", Message: "is required"})
}
if !strings.Contains(r.Email, "@") {
issues = append(issues, Issue{Field: "email", Message: "must be a valid email"})
}
return issues
}
I don’t try to re-implement full JSON Schema in Go, but I do like returning validation errors that are easy for clients to render. The pattern is: decode into a struct, validate required fields and invariants, and return a slice of {field, message} issues. This gives you a stable contract: the frontend can highlight fields without parsing English strings. I keep the validation separate from the handler so it’s testable and so the handler remains a thin adapter. For more complex domains I’d pull in a validation library, but the “hand-rolled issues array” scales surprisingly well for typical CRUD APIs. The important detail is consistency: every endpoint should return the same VALIDATION_ERROR code and the same issue shape. That uniformity is what makes client code simple.
Related snips
package api
import (
"net/http"
"runtime/debug"
)
Expose build metadata for debugging deploys
payload = {
sub: user.id,
iss: 'https://auth.example.com',
aud: 'codesnips-api',
exp: 15.minutes.from_now.to_i,
iat: Time.now.to_i,
JWT issuance and verification without common footguns
module Api
module V1
class UsersController < BaseController
def show
user = User.includes(:profile).find(params[:id])
ETags for conditional requests and caching
package dbutil
import (
"context"
"github.com/jackc/pgconn"
Retry Postgres serialization failures with bounded attempts
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: String!
GraphQL API with Spring Boot
class SignupForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :account_name, :string
attribute :email, :string
Shallow Controller, Deep Params: Form Object Pattern
Share this code
Here's the card — post it anywhere.