Skip to main content

Parameters And Metadata

VEF separates request input into two sections:

  • params: business input
  • meta: request-level control data

That split exists for RPC requests and is preserved internally for REST requests as well.

Request Model Overview

SectionPurposeTypical content
paramsbusiness payloadsearch fields, write payloads, uploaded files, command inputs
metarequest controlspaging, sorting, export format, option column mapping

Supported Typed Targets

The framework supports these request-decoding targets:

Target typeDecoded fromValidationTypical use
typed struct embedding api.PparamsYesbusiness params
typed struct embedding api.MmetaYestyped meta
page.PageablemetaYespaging
api.ParamsparamsNo typed validationraw dynamic payload
api.MetametaNo typed validationraw dynamic meta

api.P Marks Params Structs

Embed api.P in structs that should decode from Request.Params:

type CreateUserParams struct {
api.P

Username string `json:"username" validate:"required"`
Email string `json:"email" validate:"required,email"`
}

When a handler accepts CreateUserParams or *CreateUserParams, the framework:

  1. decodes params
  2. validates the struct
  3. injects the typed value

api.M Marks Meta Structs

Embed api.M in structs that should decode from Request.Meta:

type PageMeta struct {
api.M
page.Pageable
}

This is how typed request controls are injected.

Built-In Meta Helpers

The framework has built-in support for these meta-oriented helper types:

TypeMeaningNotes
page.Pageablepage number and page sizedirectly recognized as a built-in meta type
crud.Sortablesort specsusually embedded inside a typed meta struct

Important distinction:

  • page.Pageable is a built-in meta target type
  • crud.Sortable is not resolved as a standalone built-in meta type, but it works naturally when embedded in a typed api.M struct

Raw Access

If you do not want typed decoding, handlers can accept:

TypeMeaning
api.Paramsraw params map
api.Metaraw meta map

Use raw access for dynamic, proxy-style, or partially unknown payloads. Prefer typed structs for stable business APIs.

RPC Decoding Rules

For RPC requests, decoding depends on the transport content type:

RPC request typeparams sourcemeta sourceNotes
JSON bodyrequest JSON params objectrequest JSON meta objectstandard RPC shape
form requestform field params parsed as JSON stringform field meta parsed as JSON stringused for form-style clients
multipart formform field params parsed as JSON string, plus uploaded files merged into paramsform field meta parsed as JSON stringfile fields are added into params

REST Decoding Rules

For REST requests:

Input sourceLands inNotes
query stringparamsused for read filters and plain request fields
JSON body on POST / PUT / PATCHparamswrite payload
multipart fields on POST / PUT / PATCHparamsincludes uploaded files
X-Meta-* headersmetarequest-level control values

That means paging and sorting are not automatically pulled from query string into built-in meta helpers. If a handler expects meta-based controls such as page.Pageable, the caller should provide them through X-Meta-* headers or a typed meta contract.

Multipart File Support

Multipart uploads can populate params fields such as:

ShapeNotes
*multipart.FileHeaderstandard single-file upload field
raw file entries inside api.Paramsuseful for proxy-style or dynamic handlers

This is how built-in storage and import endpoints receive uploaded files.

Validation Behavior

Typed params and typed meta values are automatically validated after decoding.

Target typeValidation
typed api.P structyes
typed api.M structyes
page.Pageableyes
api.Paramsno typed validation
api.Metano typed validation

Validation uses validator.Validate(...) after decoding. If validation fails, the framework returns a bad-request style result with translated field messages.

Practical Patterns

Standard search request

type UserSearch struct {
api.P
Keyword string `json:"keyword" search:"contains,column=username|email"`
}

type UserMeta struct {
api.M
page.Pageable
crud.Sortable
}

Dynamic proxy-style request

func (*ProxyResource) Forward(params api.Params, meta api.Meta) error {
// handle raw data
return nil
}

Practical Advice

  • put business fields in params
  • put paging, sorting, export mode, and similar request controls in meta
  • prefer typed structs over raw maps for long-term maintainability
  • embed api.P and api.M explicitly so decoding intent stays obvious
  • use raw api.Params / api.Meta only when the request contract is truly dynamic

Next Step

Read Custom Handlers to see how these decoded values are injected into handler signatures.