Skip to content

Instantly share code, notes, and snippets.

@haunt98
Last active March 8, 2026 16:21
Show Gist options
  • Select an option

  • Save haunt98/5aa9089ab61e621ed7cfae6a45d437ba to your computer and use it in GitHub Desktop.

Select an option

Save haunt98/5aa9089ab61e621ed7cfae6a45d437ba to your computer and use it in GitHub Desktop.

AGENTS.md

Common

Good practices

  • Always use enum for status field
  • Push Ifs Up: Move if condition from inside function to caller when the if condition is returning early
  • Push Fors Down: Prefer passing list of objects to function instead of function inside loop of objects, to allow batch operation

Golang

Good practices

  • Provide capacity when make maps, slices
  • Use field name to init struct
  • Do not use unsigned type
  • Do not edit/update map argument inside function, to avoid race condition

Code review checklist

  • Review all string comparison ==, != to evaluate if need to use strings.EqualFold instead

Modernize style

Since go 1.26:

  • Use a := new(1)
  • Use errors.AsType instead of errors.As

Since go 1.24:

  • Use os.Root instead of os.Open
  • Use omitzero instead of omitempty

Since go 1.22:

  • Use cmp.Or as fallback mechanism

Since go 1.21:

  • Use slices.SortFunc instead of sort.Slice.
  • Use ctx.WithoutCancel to disconnect context from parent.
  • Use clear(m) to clear map entirely.

Since go 1.20:

  • Use errors.Join for multiple errors.

Since go 1.18:

  • Use any instead of interface{}.

Use gopls/modernize to modernize code.

modernize -fix -test ./...

Pkg gin-gonic/gin practices

  • Don't use c when passing context, use c.Request.Context() instead
  • Don't use c.Request.URL.Path, use c.FullPath() instead

Pkg uber-go/zap practices

  • Use MarshalLogObject when need to hide PII or long fields
  • Prefer DPanic to Panic
  • Use Fatal when init service
  • If doubt, use zap.Any

Pkg redis/go-redis practices

  • Prefer Pipelined to Pipeline

Misc pkg

  • Use spf13/cast to cast from int to string, string to int
  • Use bytedance/sonic, keep json.Marshal but prefer sonic.Unmarshal, sonic.UnmarshalString to json.Unmarshal
  • Use DATA-DOG/go-sqlmock for mock sql testing
    • Use sqlmock.QueryMatcherEqual instead of sqlmock.QueryMatcherRegexp
  • Use alicebob/miniredis for mock redis testing

Database

Primary key

  • Don't use database auto increment
  • Use UUIDv7 (sortable) instead of UUIDv4 (completely random)

Timestamp

Don't use database type timestamp (MySQL timestamp, ...), use int64 then pass the timestamp (prefer UnixMilli) to avoid date, time, location complex conversion.

JSON field

  • Use JSON_CONTAINS_PATH(col, 'one', '$.key') to check json field exist or not
  • Use col->'$.key' to get value

UTF-8

Be careful if edit/cut string which has emoji before saving to database.

NULL

If compare not equal with NULL field, remember to check NULL.

-- field_something can be NULL

-- Bad
SELECT *
FROM table
WHERE field_something != 1

-- Good
SELECT *
FROM table
WHERE (field_something IS NULL OR field_something != 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment