Back to godoc.org
github.com/System-Glitch/goyave/v2

package goyave

v2.10.2
Latest Go to latest
Published: 3 days ago | License: MIT | Module: github.com/System-Glitch/goyave/v2

Index

Constants

const (
	// ExitInvalidConfig the exit code returned when the config
	// validation doesn't pass.
	ExitInvalidConfig = 3

	// ExitNetworkError the exit code returned when an error
	// occurs when opening the network listener
	ExitNetworkError = 4

	// ExitHTTPError the exit code returned when an error
	// occurs in the HTTP server (port already in use for example)
	ExitHTTPError = 5
)

Variables

var (

	// Logger the logger for default output
	// Writes to stdout by default.
	Logger *log.Logger = log.New(os.Stdout, "", log.LstdFlags)

	// AccessLogger the logger for access. This logger
	// is used by the logging middleware.
	// Writes to stdout by default.
	AccessLogger *log.Logger = log.New(os.Stdout, "", 0)

	// ErrLogger the logger in which errors and stacktraces are written.
	// Writes to stderr by default.
	ErrLogger *log.Logger = log.New(os.Stderr, "", log.LstdFlags)
)

func ClearStartupHooks

func ClearStartupHooks()

ClearStartupHooks removes all startup hooks.

func DisableMaintenance

func DisableMaintenance()

DisableMaintenance replace the main server handler with the original router.

func EnableMaintenance

func EnableMaintenance()

EnableMaintenance replace the main server handler with the "Service Unavailable" handler.

func IsMaintenanceEnabled

func IsMaintenanceEnabled() bool

IsMaintenanceEnabled return true if the server is currently in maintenance mode.

func IsReady

func IsReady() bool

IsReady returns true if the server has finished initializing and is ready to serve incoming requests.

func RegisterStartupHook

func RegisterStartupHook(hook func())

RegisterStartupHook to execute some code once the server is ready and running.

func RunTest

func RunTest(t *testing.T, suite ITestSuite) bool

RunTest run a test suite with prior initialization of a test environment. The GOYAVE_ENV environment variable is automatically set to "test" and restored to its original value at the end of the test run. All tests are run using your project's root as working directory. This directory is determined by the presence of a "go.mod" file.

func Start

func Start(routeRegistrer func(*Router)) error

Start starts the web server. The routeRegistrer parameter is a function aimed at registering all your routes and middleware.

import (
    "github.com/System-Glitch/goyave/v2"
    "my-project/route"
)

func main() {
    if err := goyave.Start(route.Register); err != nil {
        os.Exit(err.(*goyave.Error).ExitCode)
    }
}

Errors returned can be safely type-asserted to "*goyave.Error". Panics if the server is already running.

func Stop

func Stop()

Stop gracefully shuts down the server without interrupting any active connections.

Make sure the program doesn't exit and waits instead for Stop to return.

Stop does not attempt to close nor wait for hijacked connections such as WebSockets. The caller of Stop should separately notify such long-lived connections of shutdown and wait for them to close, if desired.

type Error

type Error struct {
	ExitCode int
	Err      error
}

Error wrapper for errors directely related to the server itself. Contains an exit code and the original error.

func (*Error) Error

func (e *Error) Error() string

type Handler

type Handler func(*Response, *Request)

Handler is a controller or middleware function

func NativeHandler

func NativeHandler(handler http.Handler) Handler

NativeHandler is an adapter function for "http.Handler". With this adapter, you can plug non-Goyave handlers to your application.

Just remember that the body contains the raw data, which haven't been validated nor converted. This means that native handlers are not guaranteed to work and cannot modify the request data. Request properties, such as headers, can still be modified. Prefer implementing a Goyave handler.

This feature is a compatibility layer with the rest of the Golang web ecosystem. Prefer using Goyave handlers if possible.

type ITestSuite

type ITestSuite interface {
	RunServer(func(*Router), func())
	Timeout() time.Duration
	SetTimeout(time.Duration)
	Middleware(Middleware, *Request, Handler) *http.Response

	Get(string, map[string]string) (*http.Response, error)
	Post(string, map[string]string, io.Reader) (*http.Response, error)
	Put(string, map[string]string, io.Reader) (*http.Response, error)
	Patch(string, map[string]string, io.Reader) (*http.Response, error)
	Delete(string, map[string]string, io.Reader) (*http.Response, error)
	Request(string, string, map[string]string, io.Reader) (*http.Response, error)

	T() *testing.T
	SetT(*testing.T)

	GetBody(*http.Response) []byte
	GetJSONBody(*http.Response, interface{}) error
	CreateTestFiles(paths ...string) []filesystem.File
	WriteFile(*multipart.Writer, string, string, string)
	WriteField(*multipart.Writer, string, string)
	CreateTestRequest(*http.Request) *Request
	CreateTestResponse(http.ResponseWriter) *Response
	// contains filtered or unexported methods
}

ITestSuite is an extension of testify's Suite for Goyave-specific testing.

type Middleware

type Middleware func(Handler) Handler

Middleware function generating middleware handler function.

Request data is available to middleware, but bear in mind that it had not been validated yet. That means that you can modify or filter data. (Trim strings for example)

func NativeMiddleware

func NativeMiddleware(middleware NativeMiddlewareFunc) Middleware

NativeMiddleware is an adapter function for standard library middleware.

Native middleware work like native handlers. See "NativeHandler" for more details.

type NativeMiddlewareFunc

type NativeMiddlewareFunc func(http.Handler) http.Handler

NativeMiddlewareFunc is a function which receives an http.Handler and returns another http.Handler.

type Request

type Request struct {
	User   interface{}
	Rules  validation.RuleSet
	Data   map[string]interface{}
	Params map[string]string
	Lang   string
	// contains filtered or unexported fields
}

Request struct represents an http request. Contains the validated body in the Data attribute if the route was defined with a request generator function

func (*Request) BasicAuth

func (r *Request) BasicAuth() (username, password string, ok bool)

BasicAuth returns the username and password provided in the request's Authorization header, if the request uses HTTP Basic Authentication.

func (*Request) BearerToken

func (r *Request) BearerToken() (string, bool)

BearerToken extract the auth token from the "Authorization" header. Only takes tokens of type "Bearer". Returns empty string if no token found or the header is invalid.

func (*Request) Bool

func (r *Request) Bool(field string) bool

Bool get a bool field from the request data. Panics if the field is not a bool.

func (*Request) CORSOptions

func (r *Request) CORSOptions() *cors.Options

CORSOptions returns the CORS options applied to this request, or nil. The returned object is a copy of the options applied to the router. Therefore, altering the returned object will not alter the router's options.

func (*Request) ContentLength

func (r *Request) ContentLength() int64

ContentLength records the length of the associated content. The value -1 indicates that the length is unknown.

func (*Request) Cookies

func (r *Request) Cookies(name string) []*http.Cookie

Cookies returns the HTTP cookies sent with the request.

func (*Request) Date

func (r *Request) Date(field string) time.Time

Date get a date field from the request data. Panics if the field is not a date.

func (*Request) File

func (r *Request) File(field string) []filesystem.File

File get a file field from the request data. Panics if the field is not numeric.

func (*Request) Has

func (r *Request) Has(field string) bool

Has check if the given field exists in the request data.

func (*Request) Header

func (r *Request) Header() http.Header

Header contains the request header fields either received by the server or to be sent by the client. Header names are case-insensitive.

If the raw request has the following header lines,

Host: example.com
accept-encoding: gzip, deflate
Accept-Language: en-us
fOO: Bar
foo: two

then the header map will look like this:

Header = map[string][]string{
	"Accept-Encoding": {"gzip, deflate"},
	"Accept-Language": {"en-us"},
	"Foo": {"Bar", "two"},
}

func (*Request) IP

func (r *Request) IP(field string) net.IP

IP get an IP field from the request data. Panics if the field is not an IP.

func (*Request) Integer

func (r *Request) Integer(field string) int

Integer get an integer field from the request data. Panics if the field is not an integer.

func (*Request) Method

func (r *Request) Method() string

Method specifies the HTTP method (GET, POST, PUT, etc.).

func (*Request) Numeric

func (r *Request) Numeric(field string) float64

Numeric get a numeric field from the request data. Panics if the field is not numeric.

func (*Request) Protocol

func (r *Request) Protocol() string

Protocol the protocol used by this request, "HTTP/1.1" for example.

func (*Request) Referrer

func (r *Request) Referrer() string

Referrer returns the referring URL, if sent in the request.

func (*Request) RemoteAddress

func (r *Request) RemoteAddress() string

RemoteAddress allows to record the network address that sent the request, usually for logging.

func (*Request) Request

func (r *Request) Request() *http.Request

Request return the raw http request. Prefer using the "goyave.Request" accessors.

func (*Request) Route

func (r *Request) Route() *Route

Route returns the current route.

func (*Request) String

func (r *Request) String(field string) string

String get a string field from the request data. Panics if the field is not a string.

func (*Request) Timezone

func (r *Request) Timezone(field string) *time.Location

Timezone get a timezone field from the request data. Panics if the field is not a timezone.

func (*Request) URI

func (r *Request) URI() *url.URL

URI specifies the URI being requested. Use this if you absolutely need the raw query params, url, etc. Otherwise use the provided methods and fields of the "goyave.Request".

func (*Request) URL

func (r *Request) URL(field string) *url.URL

URL get a URL field from the request data. Panics if the field is not a URL.

func (*Request) UUID

func (r *Request) UUID(field string) uuid.UUID

UUID get a UUID field from the request data. Panics if the field is not a UUID.

func (*Request) UserAgent

func (r *Request) UserAgent() string

UserAgent returns the client's User-Agent, if sent in the request.

type Response

type Response struct {
	// contains filtered or unexported fields
}

Response represents a controller response.

func CreateTestResponse

func CreateTestResponse(recorder http.ResponseWriter) *Response

CreateTestResponse create an empty response with the given response writer. This function is aimed at making it easier to unit test Responses.

Deprecated: Use goyave.TestSuite.CreateTestResponse instead.

writer := httptest.NewRecorder()
response := goyave.CreateTestResponse(writer)
response.Status(http.StatusNoContent)
result := writer.Result()
fmt.Println(result.StatusCode) // 204

func (*Response) Cookie

func (r *Response) Cookie(cookie *http.Cookie)

Cookie add a Set-Cookie header to the response. The provided cookie must have a valid Name. Invalid cookies may be silently dropped.

func (*Response) Download

func (r *Response) Download(file string, fileName string) error

Download write a file as an attachment element. Automatically detects the file MIME type and sets the "Content-Type" header accordingly. If the file doesn't exist, respond with status 404 Not Found. The given path can be relative or absolute.

The "fileName" parameter defines the name the client will see. In other words, it sets the header "Content-Disposition" to "attachment; filename="${fileName}""

If you want the file to be sent as an inline element ("Content-Disposition: inline"), use the "File" function instead.

func (*Response) Error

func (r *Response) Error(err interface{}) error

Error print the error in the console and return it with an error code 500. If debugging is enabled in the config, the error is also written in the response and the stacktrace is printed in the console. If debugging is not enabled, only the stauts code is set, which means you can still write to the response, or use your error status handler.

func (*Response) File

func (r *Response) File(file string) error

File write a file as an inline element. Automatically detects the file MIME type and sets the "Content-Type" header accordingly. If the file doesn't exist, respond with status 404 Not Found. The given path can be relative or absolute.

If you want the file to be sent as a download ("Content-Disposition: attachment"), use the "Download" function instead.

func (*Response) GetError

func (r *Response) GetError() interface{}

GetError return the value which caused a panic in the request's handling, or nil.

func (*Response) GetStatus

func (r *Response) GetStatus() int

GetStatus return the response code for this request or 0 if not yet set.

func (*Response) HandleDatabaseError

func (r *Response) HandleDatabaseError(db *gorm.DB) bool

HandleDatabaseError takes a database query result and checks if any error has occurred.

Automatically writes HTTP status code 404 Not Found if the error is a "Not found" error. Calls "Response.Error()" if there is another type of error.

Returns true if there is no error.

func (*Response) Header

func (r *Response) Header() http.Header

Header returns the header map that will be sent.

func (*Response) JSON

func (r *Response) JSON(responseCode int, data interface{}) error

JSON write json data as a response. Also sets the "Content-Type" header automatically.

If a model is passed as parameter, its hidden fields will be removed.

func (*Response) Redirect

func (r *Response) Redirect(url string)

Redirect send a permanent redirect response

func (*Response) Render

func (r *Response) Render(responseCode int, templatePath string, data interface{}) error

Render a text template with the given data. The template path is relative to the "resources/template" directory.

func (*Response) RenderHTML

func (r *Response) RenderHTML(responseCode int, templatePath string, data interface{}) error

RenderHTML an HTML template with the given data. The template path is relative to the "resources/template" directory.

func (*Response) SetWriter

func (r *Response) SetWriter(writer io.Writer)

SetWriter set the writer used to write the response. This can be used to chain writers, for example to enable gzip compression, or for logging.

The original http.ResponseWriter is always kept.

func (*Response) Status

func (r *Response) Status(status int)

Status set the response status code. Calling this method a second time will have no effect.

func (*Response) String

func (r *Response) String(responseCode int, message string) error

String write a string as a response

func (*Response) TemporaryRedirect

func (r *Response) TemporaryRedirect(url string)

TemporaryRedirect send a temporary redirect response

func (*Response) Write

func (r *Response) Write(data []byte) (int, error)

Write writes the data as a response. See http.ResponseWriter.Write

func (*Response) WriteHeader

func (r *Response) WriteHeader(status int)

WriteHeader sends an HTTP response header with the provided status code. Prefer using "Status()" method instead. Calling this method a second time will have no effect.

func (*Response) Writer

func (r *Response) Writer() io.Writer

Writer return the current writer used to write the response. Note that the returned writer is not necessarily a http.ResponseWriter, as it can be replaced using SetWriter.

type Route

type Route struct {
	// contains filtered or unexported fields
}

Route stores information for matching and serving.

func GetRoute

func GetRoute(name string) *Route

GetRoute get a named route. Returns nil if the route doesn't exist.

func (*Route) BuildURL

func (r *Route) BuildURL(parameters ...string) string

BuildURL build a full URL pointing to this route. Panics if the amount of parameters doesn't match the amount of actual parameters for this route.

func (*Route) GetFullURI

func (r *Route) GetFullURI() string

GetFullURI get the full URI of this route.

Note that this URI may contain route parameters in their définition format. Use the request's URI if you want to see the URI as it was requested by the client.

func (*Route) GetMethods

func (r *Route) GetMethods() []string

GetMethods returns the methods the route matches against.

func (*Route) GetName

func (r *Route) GetName() string

GetName get the name of this route.

func (*Route) GetURI

func (r *Route) GetURI() string

GetURI get the URI of this route. The returned URI is relative to the parent router of this route, it is NOT the full path to this route.

Note that this URI may contain route parameters in their définition format. Use the request's URI if you want to see the URI as it was requested by the client.

func (*Route) Name

func (r *Route) Name(name string) *Route

Name set the name of the route. Panics if a route with the same name already exists. Returns itself.

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router registers routes to be matched and executes a handler.

func (*Router) CORS

func (r *Router) CORS(options *cors.Options)

CORS set the CORS options for this route group. If the options are not nil, the CORS middleware is automatically added.

func (*Router) Delete

func (r *Router) Delete(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Delete registers a new route wit the DELETE method.

func (*Router) Get

func (r *Router) Get(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Get registers a new route wit the GET method.

func (*Router) GetRoute

func (r *Router) GetRoute(name string) *Route

GetRoute get a named route. Returns nil if the route doesn't exist.

func (*Router) Middleware

func (r *Router) Middleware(middleware ...Middleware)

Middleware apply one or more middleware to the route group.

func (*Router) Options

func (r *Router) Options(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Options registers a new route wit the OPTIONS method.

func (*Router) Patch

func (r *Router) Patch(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Patch registers a new route wit the PATCH method.

func (*Router) Post

func (r *Router) Post(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Post registers a new route wit the POST method.

func (*Router) Put

func (r *Router) Put(uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Put registers a new route wit the PUT method.

func (*Router) Route

func (r *Router) Route(methods string, uri string, handler Handler, validationRules validation.RuleSet, middleware ...Middleware) *Route

Route register a new route.

Multiple methods can be passed using a pipe-separated string.

"PUT|PATCH"

The validation rules set is optional. If you don't want your route to be validated, pass "nil".

If the router has CORS options set, the "OPTIONS" method is automatically added to the matcher if it's missing, so it allows preflight requests.

Returns the generated route.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP dispatches the handler registered in the matched route.

func (*Router) Static

func (r *Router) Static(uri string, directory string, download bool, middleware ...Middleware)

Static serve a directory and its subdirectories of static resources. Set the "download" parameter to true if you want the files to be sent as an attachment instead of an inline element.

If no file is given in the url, or if the given file is a directory, the handler will send the "index.html" file if it exists.

func (*Router) StatusHandler

func (r *Router) StatusHandler(handler Handler, status int, additionalStatuses ...int)

StatusHandler set a handler for responses with an empty body. The handler will be automatically executed if the request's life-cycle reaches its end and nothing has been written in the response body.

Multiple status codes can be given. The handler will be executed if one of them matches.

This method can be used to define custom error handlers for example.

Status handlers are inherited as a copy in sub-routers. Modifying a child's status handler will not modify its parent's.

Codes in the 400 and 500 ranges have a default status handler.

func (*Router) Subrouter

func (r *Router) Subrouter(prefix string) *Router

Subrouter create a new sub-router from this router. Use subrouters to create route groups and to apply middleware to multiple routes. CORS options are also inherited.

type TestSuite

type TestSuite struct {
	testify.Suite
	// contains filtered or unexported fields
}

TestSuite is an extension of testify's Suite for Goyave-specific testing.

func (*TestSuite) ClearDatabase

func (s *TestSuite) ClearDatabase()

ClearDatabase delete all records in all tables. This function only clears the tables of registered models.

func (*TestSuite) ClearDatabaseTables

func (s *TestSuite) ClearDatabaseTables()

ClearDatabaseTables drop all tables. This function only clears the tables of registered models.

func (*TestSuite) CreateTestFiles

func (s *TestSuite) CreateTestFiles(paths ...string) []filesystem.File

CreateTestFiles create a slice of "filesystem.File" from the given paths. Files are passed to a temporary http request and parsed as Multipart form, to reproduce the way files are obtained in real scenarios.

func (*TestSuite) CreateTestRequest

func (s *TestSuite) CreateTestRequest(rawRequest *http.Request) *Request

CreateTestRequest create a "goyave.Request" from the given raw request. This function is aimed at making it easier to unit test Requests.

If passed request is "nil", a default GET request to "/" is used.

rawRequest := httptest.NewRequest("GET", "/test-route", nil)
rawRequest.Header.Set("Content-Type", "application/json")
request := goyave.CreateTestRequest(rawRequest)
request.Lang = "en-US"
request.Data = map[string]interface{}{"field": "value"}

func (*TestSuite) CreateTestResponse

func (s *TestSuite) CreateTestResponse(recorder http.ResponseWriter) *Response

CreateTestResponse create an empty response with the given response writer. This function is aimed at making it easier to unit test Responses.

writer := httptest.NewRecorder()
response := suite.CreateTestResponse(writer)
response.Status(http.StatusNoContent)
result := writer.Result()
fmt.Println(result.StatusCode) // 204

func (*TestSuite) CreateTestResponseWithRequest

func (s *TestSuite) CreateTestResponseWithRequest(recorder http.ResponseWriter, rawRequest *http.Request) *Response

CreateTestResponseWithRequest create an empty response with the given response writer HTTP request. This function is aimed at making it easier to unit test Responses needing the raw request's information, such as redirects.

writer := httptest.NewRecorder()
rawRequest := httptest.NewRequest("POST", "/test-route", strings.NewReader("body"))
response := suite.CreateTestResponseWithRequest(writer, rawRequest)
response.Status(http.StatusNoContent)
result := writer.Result()
fmt.Println(result.StatusCode) // 204

func (*TestSuite) Delete

func (s *TestSuite) Delete(route string, headers map[string]string, body io.Reader) (*http.Response, error)

Delete execute a DELETE request on the given route. Headers and body are optional.

func (*TestSuite) Get

func (s *TestSuite) Get(route string, headers map[string]string) (*http.Response, error)

Get execute a GET request on the given route. Headers are optional.

func (*TestSuite) GetBody

func (s *TestSuite) GetBody(response *http.Response) []byte

GetBody read the whole body of a response. If read failed, test fails and return empty byte slice.

func (*TestSuite) GetJSONBody

func (s *TestSuite) GetJSONBody(response *http.Response, data interface{}) error

GetJSONBody read the whole body of a response and decode it as JSON. If read or decode failed, test fails.

func (*TestSuite) Middleware

func (s *TestSuite) Middleware(middleware Middleware, request *Request, procedure Handler) *http.Response

Middleware executes the given middleware and returns the HTTP response. Core middleware (recovery, parsing and language) is not executed.

func (*TestSuite) Patch

func (s *TestSuite) Patch(route string, headers map[string]string, body io.Reader) (*http.Response, error)

Patch execute a PATCH request on the given route. Headers and body are optional.

func (*TestSuite) Post

func (s *TestSuite) Post(route string, headers map[string]string, body io.Reader) (*http.Response, error)

Post execute a POST request on the given route. Headers and body are optional.

func (*TestSuite) Put

func (s *TestSuite) Put(route string, headers map[string]string, body io.Reader) (*http.Response, error)

Put execute a PUT request on the given route. Headers and body are optional.

func (*TestSuite) Request

func (s *TestSuite) Request(method, route string, headers map[string]string, body io.Reader) (*http.Response, error)

Request execute a request on the given route. Headers and body are optional.

func (*TestSuite) RunServer

func (s *TestSuite) RunServer(routeRegistrer func(*Router), procedure func())

RunServer start the application and run the given functional test procedure.

This function is the equivalent of "goyave.Start()". The test fails if the suite's timeout is exceeded. The server automatically shuts down when the function ends. This function is synchronized, that means that the server is properly stopped when the function returns.

func (*TestSuite) SetTimeout

func (s *TestSuite) SetTimeout(timeout time.Duration)

SetTimeout set the timeout for test failure when using RunServer or requests.

func (*TestSuite) Timeout

func (s *TestSuite) Timeout() time.Duration

Timeout get the timeout for test failure when using RunServer or requests.

func (*TestSuite) WriteField

func (s *TestSuite) WriteField(writer *multipart.Writer, fieldName, value string)

WriteField create and write a new multipart form field. The test fails if the field couldn't be written.

func (*TestSuite) WriteFile

func (s *TestSuite) WriteFile(writer *multipart.Writer, path, fieldName, fileName string)

WriteFile write a file to the given writer. This function is handy for file upload testing. The test fails if an error occurred.

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
f or F : Jump to identifier