Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
/appPublic

🚀 Full featured HTTP framework for web apps

License

NotificationsYou must be signed in to change notification settings

gowww/app

Repository files navigation

gowww/app

gowww/app is a full featured HTTP framework for any web app.
It greatly increases productivity by providing helpers at all levels while maintaining best performance.

Start

  1. Install Go

  2. Install gowww/app:

    go get github.com/gowww/app
  3. Import it in your new app:

    import"github.com/gowww/app"

Routing

There are methods for common HTTP methods:

app.Get("/",func(c*app.Context) {// Write response for GET /})app.Post("/",func(c*app.Context) {// Write response for POST /})app.Put("/",func(c*app.Context) {// Write response for PUT /})app.Patch("/",func(c*app.Context) {// Write response for PATCH /})app.Delete("/",func(c*app.Context) {// Write response for DELETE /})

Path parameters

Named

A named parameter begins with: and matches any value until the next/ in path.

To retrieve the value, askContext.PathValue.
It will return the value as a string (empty if the parameter doesn't exist).

Example, with a parameterid:

app.Get("/users/:id",func(c*app.Context) {id:=c.PathValue("id")fmt.Fprintf(w,"Page of user #%s",id)}))

Regular expressions

If a parameter must match an exact pattern (digits only, for example), you can also set aregular expression constraint just after the parameter name and another::

app.Get(`/users/:id:^\d+$`,func(c*app.Context) {id:=c.PathValue("id")fmt.Fprintf(w,"Page of user #%s",id)}))

If you don't need to retrieve the parameter value but only use a regular expression, you can omit the parameter name.

Wildcard

A trailing slash behaves like a wildcard by matching the beginning of the request path and keeping the rest as a parameter value, under*:

rt.Get("/files/",func(c*app.Context) {filepath:=c.PathValue("*")fmt.Fprintf(w,"Get file %s",filepath)}))

For more details, seegowww/router.

Groups

A routing group works like the top-level router but prefixes all subroute paths:

api:=app.Group("/api"){v1:=api.Group("/v1"){v1.Get("/user",func(c*app.Context) {/* Write response for GET /api/v1/user */ })v1.Get("/item",func(c*app.Context) {/* Write response for GET /api/v1/item */ })}v2:=api.Group("/v2"){v2.Get("/user",func(c*app.Context) {/* Write response for GET /api/v2/user */ })v2.Get("/item",func(c*app.Context) {/* Write response for GET /api/v2/item */ })}}

Errors

You can set a custom "not found" handler withNotFound:

app.NotFound(func(c*app.Context) {c.Status(http.StatusNotFound)c.View("notFound")})

The app is also recovered from panics so you can set a custom "serving error" handler (which is used only when the response is not already written) withError and retrieve the recovered error value withContext.Error:

app.Error(func(c*app.Context) {c.Status(http.StatusInternalServerError)ifc.Error()==ErrCannotOpenFile {c.View("errorStorage")return}c.View("error")})

Context

AContext is always used inside aHandler.
It contains the original request and response writer but provides all the necessary helpers to access them:

Request

UseContext.Req to access the original request:

app.Get("/",func(c*app.Context) {r:=c.Req})

UseContext.FormValue to access a value from URL or body.
You can also useContext.HasFormValue to check its existence:

app.Get("/",func(c*app.Context) {ifc.HasFormValue("id") {id:=c.FormValue("id")}})

Response

UseContext.Res to access the original response writer:

app.Get("/",func(c*app.Context) {w:=c.Res})

UseContext.Text orContext.Bytes to send a string:

app.Get("/",func(c*app.Context) {c.Text("Hello")c.Bytes([]byte("World"))})

UseContext.JSON to send a JSON formatted response (if implemented by argument,JSON() interface{} will be used):

app.Get(`/users/:id:^\d+$/files/`,func(c*app.Context) {c.JSON(map[string]interface{}{"userID":c.PathValue("id"),"filepath":c.PathValue("*"),})})

UseContext.Status to set the response status code:

app.Get("/",func(c*app.Context) {c.Status(http.StatusCreated)})

UseContext.NotFound to send a "not found" response:

app.Get("/",func(c*app.Context) {c.NotFound()})

UseContext.Panic to log an error and send a "serving error" response:

app.Get("/",func(c*app.Context) {c.Panic("database connection failed")})

UseContext.Redirect to redirect the client:

app.Get("/old",func(c*app.Context) {c.Redirect("/new",http.StatusMovedPermanently)})

UseContext.Push to initiate an HTTP/2 server push:

app.Get("/",func(c*app.Context) {c.Push("/static/main.css",nil)})

Values

You can use context values kept inside the context for future usage downstream (like views or subhandlers).

UseContext.Set to set a value:

app.Get("/",func(c*app.Context) {c.Set("clientCountry","UK")})

UseContext.Get to retrieve a value:

app.Get("/",func(c*app.Context) {clientCountry:=c.Get("clientCountry")})

Views

Views are standardGo HTML templates and must be stored inside theviews directory.
They are automatically parsed during launch.

UseContext.View to send a view:

app.Get("/",func(c*app.Context) {c.View("home")})

Data

Use aViewData map to pass data to a view.

You can also useGlobalViewData to set data for all views:

app.GlobalViewData(app.ViewData{"appName":"My app",})app.Get("/",func(c*app.Context) {user:=&User{ID:1,Name:"John Doe",}c.View("home", app.ViewData{"user":user,})})

Inviews/home.gohtml:

{{define "home"}}<h1>Hello {{.user.Name}} ({{.c.Req.RemoteAddr}}) and welcome on {{.appName}}!</h1>{{end}}

Built-in

This data is always passed to the views, out of the box:

DataDescription
.cThe currentContext.
.envProductionTells if the app is run with the production flag.
.errorsSeevalidation.

Functions

UseGlobalViewFuncs to set functions for all views:

app.GlobalViewFuncs(app.ViewFuncs{"pathescape":url.PathEscape,})app.Get("/posts/new",func(c*app.Context) {c.View("postsNew")})

Inviews/posts.gohtml:

{{define "postsNew"}}<ahref="/sign-in?return-to={{pathescape"/posts/new"}}">Sign in</a>{{end}}

Built-in

In addition to the functions provided by the standardtemplate package, these function are also available out of the box:

FunctionDescriptionUsage
assetAppends the file hash to the name of a static file from thestatic directory.{{asset "videos/loop.mp4"}}
googlefontsSets HTML tag forGoogle Fonts stylesheet and given font(s).{{googlefonts "Open+Sans:400,700|Spectral"}}
nl2brConverts\n to HTML<br>.{{nl2br "line one\nline two"}}
safehtmlPrevents string to be escaped. Be careful.{{safehtml "<strong>word</strong>"}}
scriptSets HTML tag for a script from thestatic/script directory.{{script "main.js"}}
styleSets HTML tag for a stylesheet from thestatic/style directory.{{style "main.css"}}

Validation

Validation is handled bygowww/check.

Firstly, make aChecker withrules for keys:

userChecker:= check.Checker{"email":   {check.Required,check.Email,check.Unique(db,"users","email","?")},"phone":   {check.Phone},"picture": {check.MaxFileSize(5000000),check.Image},}

The rules order is significant so for example, it's smarter to check the format of a value before its uniqueness, avoiding some useless database requests.

UseContext.Check to check the request against a checker:

errs:=c.Check(userChecker)

UseErrors.Empty orErrors.NotEmpty to know if there are errors and handle them like you want.
You can also translate error messages withContext.TErrors:

iferrs.NotEmpty() {c.Status(http.StatusBadRequest)c.View(view, app.ViewData{"errors":errs})return}

But usually, when a check fails, you only want to send a response with error messages.
Here comes theBadRequest shortcut which receives a checker and a view name.
If you don't provide a view name (empty string), the response will be a JSON errors map.

If the check fails, it sets the status to "400 Bad Request", sends the response (view or JSON) and returnstrue, allowing you to exit from the handler:

app.Post("/join",func(c*app.Context) {ifc.BadRequest(userChecker,"join") {return}// Handle request confidently})

In views, you can retrieve theTranslatedErrors map under keyerrors which is nevernil in view data:

<inputtype="email"name="email"value="{{.email}}">{{if .errors.Has "email"}}<divclass="error">{{.errors.First "email"}}</div>{{end}}

Internationalization

Internationalization is handled bygowww/i18n.

Firstly, make your translations map (string to string, for each language):

locales:= i18n.Locales{language.English: {"hello":"Hello!",},language.French: {"hello":"Bonjour !",},}

UseLocalize to register it and set the default locale (used as a fallback):

app.Localize(locales,language.English)

MethodsContext.T,Context.Tn,Context.THTML andContext.TnHTML are now operational.
As theContext is always part of the view data, you can use these methods in views:

<h1>{{.c.T "hello"}}</h1>

Static files

Static files must be stored inside thestatic directory.
They are automatically accessible from the/static/ path prefix.

Running

CallRun at the end of your main function:

app.Run()

By default, your app will listen and serve on:8080.
But you can change this address by using flag-a when running your app:

./myapp -a :1234

Middlewares

Custom middlewares can be used if they are compatible with standard interfacenet/http.Handler.
They can be set for:

  • The entire app:

    app.Run(hand1,hand2,hand3)
  • A group:

    api:=app.Group("/api",hand1,hand2,hand3)
  • A single route:

    api:=app.Get("/",func(c*app.Context) {// Write response for GET /},hand1,hand2,hand3)

First handler wraps the second and so on.



GoDocBuildCoverageGo ReportStatus Unstable


[8]ページ先頭

©2009-2025 Movatter.jp