Skip to content

Latest commit

 

History

History
256 lines (188 loc) · 9.5 KB

File metadata and controls

256 lines (188 loc) · 9.5 KB

Template Name Syntax Reference

Complete specification for Muxt template naming. Use when pair programming to validate route definitions.

Syntax

[METHOD ][HOST]/PATH[ HTTP_STATUS][ CALL]

All components:

{{define "GET example.com/greet/{language} 200 Greeting(ctx, language)"}}{{end}}

Minimal (path only):

{{define "/"}}{{end}}

Key rules:

  • Templates without matching names are ignored (not an error)
  • Path is required, all other components optional
  • Space-separated components, order matters
  • Uses Go 1.22+ http.ServeMux pattern matching

Quick Reference Table

Component Format Example Required
METHOD GET, POST, PUT, PATCH, DELETE GET No
HOST example.com api.example.com No
PATH /path/{param} /user/{id} Yes
STATUS 200 or http.StatusOK 201 No
CALL Method(args...) GetUser(ctx, id) No

Path Patterns

Basic Paths

{{define "GET /"}}{{end}}              <!-- Root -->
{{define "GET /about"}}{{end}}         <!-- Static path -->
{{define "GET /user/{id}"}}{{end}}     <!-- Path parameter -->
{{define "GET /user/{id}/post/{postID}"}}{{end}}  <!-- Multiple parameters -->

tutorial_basic_route.txt · howto_path_param.txt

Path Matching Modes

{{define "GET /{$}"}}{{end}}           <!-- Exact: "/" only, not "/foo" -->
{{define "GET /static/"}}{{end}}       <!-- Prefix: "/static/", "/static/foo", "/static/foo/bar" -->
{{define "GET /files/{path...}"}}{{end}}  <!-- Wildcard: captures "/files/a/b/c" as path="a/b/c" -->

Note: /{$} vs / behavior differs. Former is exact match, latter matches prefix.

reference_path_exact_match.txt · reference_path_prefix.txt

Path Parameters Are Type-Safe

{{define "GET /article/{id} GetArticle(ctx, id)"}}{{end}}
func (s Server) GetArticle(ctx context.Context, id int) (Article, error) {
    // id auto-parsed from string → int
    // Parse failure → 400 Bad Request (automatic)
}

Note: Path param names must match method param names exactly. Type conversion is automatic based on method signature.

howto_arg_path_param.txt

HTTP Methods

{{define "GET /posts"}}{{end}}          <!-- Read -->
{{define "POST /posts"}}{{end}}         <!-- Create -->
{{define "PUT /posts/{id}"}}{{end}}     <!-- Replace -->
{{define "PATCH /posts/{id}"}}{{end}}   <!-- Update -->
{{define "DELETE /posts/{id}"}}{{end}}  <!-- Delete -->

Without method prefix: Matches all methods (GET, POST, PUT, PATCH, DELETE, etc.)

howto_patch_method.txt

Status Codes

Three formats:

{{define "POST /user 201 CreateUser(ctx, form)"}}{{end}}      <!-- Integer with method -->
{{define "GET /admin http.StatusUnauthorized"}}{{end}}        <!-- Constant -->
{{define "GET /error 400"}}{{end}}                             <!-- Integer -->

Status code precedence:

  1. Template name (shown above)
  2. Result type with StatusCode() method
  3. Result type with StatusCode field
  4. Error with StatusCode() method
  5. Template .StatusCode(int) call
  6. Default (200 for success, 500 for errors)

Use template name for static codes (201 for POST), methods for dynamic codes (404 from errors).

reference_status_codes.txt

Call Expressions

Syntax

MethodName(arg1, arg2, ...)

No spaces allowed between method name and parentheses. Arguments are comma-separated identifiers.

Parameter Sources

Parameter Name Type Source Auto-parsed
ctx context.Context request.Context() N/A
request *http.Request Direct N/A
response http.ResponseWriter Direct N/A
form struct or url.Values request.Form (after ParseForm) Yes
multipart struct or *multipart.Form request.MultipartForm (after ParseMultipartForm) Yes
Path param Any parseable request.PathValue(name) Yes
Form field Any parseable request.Form.Get(name) Yes

form and multipart are mutually exclusive in the same call site. Use form for routes that handle application/x-www-form-urlencoded bodies and multipart for routes that handle multipart/form-data (file uploads, etc.). In struct-binding mode, multipart additionally supports *multipart.FileHeader and []*multipart.FileHeader fields, sourced from request.MultipartForm.File. The default maxMemory for ParseMultipartForm is 32 MiB; override with the --output-multipart-max-memory=<size> generator flag (e.g. 64MB, 128MiB). Per mime/multipart's standard semantics, upload data exceeding maxMemory spills to the OS temp directory.

Parseable types: string, int*, uint*, bool, encoding.TextUnmarshaler

Examples

{{define "GET /profile Profile(ctx)"}}{{end}}
{{define "POST /login Login(ctx, form)"}}{{end}}  <!-- Form fields -->
{{define "GET /user/{id} GetUser(ctx, id)"}}{{end}}  <!-- Path param -->
{{define "GET /user/{userID}/post/{postID} GetPost(ctx, userID, postID)"}}{{end}}  <!-- Multiple path params -->
{{define "POST /upload Upload(ctx, response, request)"}}{{end}}  <!-- HTTP primitives -->

Parameter names in template must match method signature exactly. Case-sensitive.

howto_call_method.txt · howto_call_with_multiple_args.txt · howto_arg_context.txt

Host Matching

{{define "api.example.com/v1/users ListUsers(ctx)"}}{{end}} <!-- Specific host -->
{{define "admin.example.com/ AdminHome(ctx)"}}{{end}}       <!-- Admin subdomain -->
{{define "example.com/{$} Home(ctx)"}}{{end}}               <!-- Exact host + path -->

Host patterns enable multi-tenant apps or API versioning by subdomain. Omit host to match all.

Common Patterns

REST resources:

{{define "GET /posts ListPosts(ctx)"}}{{end}}
{{define "POST /posts 201 CreatePost(ctx, form)"}}{{end}}
{{define "GET /posts/{id} GetPost(ctx, id)"}}{{end}}
{{define "PUT /posts/{id} UpdatePost(ctx, id, form)"}}{{end}}
{{define "DELETE /posts/{id} 204 DeletePost(ctx, id)"}}{{end}}

Nested resources:

{{define "GET /users/{userID}/posts/{postID} GetUserPost(ctx, userID, postID)"}}{{end}}

File serving:

{{define "GET /static/ ServeStatic(response, request)"}}{{end}}

Wildcards for paths:

{{define "GET /files/{path...} ServeFile(ctx, path)"}}{{end}}  <!-- path captures "a/b/c.txt" -->

reference_path_exact_match.txt

Go 1.22+ ServeMux Behavior

Muxt uses http.ServeMux pattern matching (docs):

  • "/index.html" — path only, any host/method
  • "GET /static/" — method + path prefix
  • "example.com/" — host + any path
  • "example.com/{$}" — host + exact path "/"
  • "/b/{bucket}/o/{name...}" — segments + wildcard

Precedence: Most specific pattern wins. GET /posts/{id} beats /posts/{id} beats /{path...}.

Formal Grammar (BNF)

<route>        ::= [<method> " "] [<host>] <path> [" " <status>] [" " <call>]
<method>       ::= "GET" | "POST" | "PUT" | "PATCH" | "DELETE"
<host>         ::= <hostname> | <ipv4>
<path>         ::= "/" [<segment> [<path>] ["/"]]
<status>       ::= <integer> | <identifier> "." <identifier>
<call>         ::= <identifier> "(" [<identifier> {"," <identifier>}] ")"
<identifier>   ::= <letter> {<letter> | <digit> | "_"}

Notes: Path segments may include {param} or {param...}. Unreserved chars: [a-zA-Z0-9-_.~].

Test Files by Category

Basics:

Path patterns:

Call expressions:

Status codes:

Forms:

Complete apps:

Error cases:

Browse all: cmd/muxt/testdata/