Skip to main content

v-veb

Writing V web applications with veb - the App and Context structs, route attributes with path parameters, ctx.html and ctx.json, templates with $tmpl and $veb.html, middleware with Middleware.use and route_use, shared state with shared and lock, and static file mounting. Use when creating or changing a veb server, adding a route or handler, returning JSON or HTML, adding middleware, or serving files. Does not cover concurrency in general (see v-concurrency), the language rules (see v-lang), the build loop (see v-workflow), scripting a task in V (see v-scripts), or the wider command surface (see v-tools).

소스 정보

저장소
vlang/v
최근 소스 활동
2026년 10월 11일 21:14
감지된 SKILL.md 언어
영어
스타
38,054
포크
2,309

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
3 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
v-veb
description
Writing V web applications with veb - the App and Context structs, route attributes with path parameters, ctx.html and ctx.json, templates with $tmpl and $veb.html, middleware with Middleware.use and route_use, shared state with shared and lock, and static file mounting. Use when creating or changing a veb server, adding a route or handler, returning JSON or HTML, adding middleware, or serving files. Does not cover concurrency in general (see v-concurrency), the language rules (see v-lang), the build loop (see v-workflow), scripting a task in V (see v-scripts), or the wider command surface (see v-tools).
license
MIT
# veb, V's web framework A veb server is two structs and a `main`. Handlers are methods on `App`, and every request runs with the whole `App` shared across threads. ## Resource Routing - `references/ROUTES.md` - Read when adding a route, a path parameter, or a response body. - `references/MIDDLEWARE.md` - Read when adding cross-cutting behaviour, shared state, or static files. ## Quick Reference | Need | Do | | --- | --- | | A route | `@['/path']` above a `pub fn (mut app App) handler(mut ctx Context) veb.Result` | | A path parameter | `@['/users/:id']` and an extra `id string` argument | | A specific method | `@[post]` or `@['/upload'; post]` | | HTML | `return $veb.html()` or `return $veb.html('page.html')` | | JSON | `return ctx.json(payload)` | | Plain text | `return ctx.text('...')` | | Middleware | `app.Middleware.use(handler: f)` | | Middleware for a path | `app.Middleware.route_use('/admin/:path...', handler: f)` | | Shared state | `field shared T`, mutated inside `lock app.state { }` | | Serve files | `app.mount_static_folder_at(...)` | | Serve a folder at root | `app.handle_static(directory_path, root)` | ## The shape of a server ```v ignore import veb const port = 8080 pub struct App {} struct Context { veb.Context } fn main() { mut app := &App{} veb.run[App, Context](mut app, port) } @['/'] pub fn (mut app App) index(mut ctx Context) veb.Result { return ctx.text('hello') } @[post] pub fn (mut app App) submit(mut ctx Context) veb.Result { return ctx.json({ok: true}) } ``` Three things to notice: - `App` is `pub` and `Context` embeds `veb.Context`. Both are type arguments to `veb.run`, which is how veb knows your types. - A handler takes `mut ctx Context` and returns `veb.Result`. Return the result of a `ctx` method rather than constructing one. - `mut app` in the signature means the method may mutate `App`. A read-only handler takes `app &App`, and veb accepts that too. ## Routes The attribute is a list of paths. Without a leading `/`, it is an HTTP method with the default path. ```v ignore @['/users/:user'] pub fn (mut app App) user_endpoint(mut ctx Context, user string) veb.Result { return ctx.json({user: user}) } @[post] pub fn (mut app App) create(mut ctx Context) veb.Result { ... } @['/upload'; post] pub fn (mut app App) upload(mut ctx Context) veb.Result { ... } ``` A `:name` in the path becomes an argument **after** `ctx`. A `:name...` at the end captures the rest of the path. See `references/ROUTES.md` for matching rules and ordering. ## Shared state `App` is shared across request threads, so a mutable field needs to say so, and every write needs a lock: ```v ignore pub struct App { mut: state shared State } struct State { mut: hits int } pub fn (mut app App) index(mut ctx Context) veb.Result { lock app.state { app.state.hits++ } return ctx.text('${app.state.hits}') } ``` `shared` is what makes the field shared rather than per-request. Omitting it, or writing without the `lock`, is a data race — and it is the mistake that matters most in a veb app. ## Middleware Middleware wraps requests. Global for the app, or scoped to a path: ```v ignore struct App { veb.Middleware[Context] } fn main() { mut app := &App{} // Chained, evaluated in order. app.Middleware.use(handler: other_func1) app.Middleware.use(handler: add_headers) // Only for matching paths. app.Middleware.route_use('/admin/:path...', handler: check_auth) veb.run[App, Context](mut app, http_port) } ``` A middleware handler takes `mut ctx Context` and returns a `bool`. Return `true` to continue the chain; return `false` to stop it, which is how a middleware short circuits a request. See `references/MIDDLEWARE.md`. ## Templates `$veb.html()` renders the templates directory; `$veb.html('name.html')` renders one file; `$tmpl` renders a string in memory, which is how a layout is composed with a page: ```v ignore @['/'] pub fn (app &App) index(mut ctx Context) veb.Result { content := $tmpl('templates/index.html') base := $tmpl('templates/base.html') return ctx.html(base) } ``` ## Validation A veb app is checked the same way as any V code, and `-check` catches most of it — including a handler whose signature does not match what veb expects: ```bash v -check -shared path/to/veb_app.v # library-shaped: needs -shared v fmt -verify path/to/veb_app.v v run path/to/main.v ``` See [v-workflow](../v-workflow/SKILL.md) for the full loop. ## Related Skills - **Concurrency**: see [v-concurrency](../v-concurrency/SKILL.md) for what `shared` means and the lock discipline that goes with it. - **The build loop**: see [v-workflow](../v-workflow/SKILL.md) for `-check`, `-shared`, `fmt -verify` and the other flags. - **The language rules**: see [v-lang](../v-lang/SKILL.md) for `mut` and for `?T` versus `!T` when a handler has to return an error.
GitHub에서 보기