stgin

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 4, 2022 License: MIT Imports: 18 Imported by: 1

README

STGIN

stgin is a functional RESTful API server framework that provides easy APIs in order to maintain your application RESTful API server.

Installation

You can use the following command to add stgin into your application.

go get github.com/AminMal/stgin

Quick Start

stgin concentrates a lot about making a well-structured application. Let's take a look at the following application structure, this is just a part of a simple application (health checking part).

  /project
    ... other packages you might need (i.e., users, authentication, inventory, ...)
    /health
      init.go
      models.go
      apis.go
      ... other things you might need
    init.go
    main.go

Let's start defining health APIs:

// /health/apis.go file

package health

import "github.com/AminMal/stgin"
// #recommended
func getHealthAPI(request stgin.RequestContext) stgin.Status {
    healthResponse := getHealth() // some method implemented in package
    // model is defined earlier in models.go
    if healthResponse.ok {
        return stgin.Ok(stgin.Json(&healthResponse))
    } else {
        return stgin.InternalServerError(stgin.Json(&healthResponse))
    }
}
// you can also define APIs as variable:
// var someAPI stgin.API = func(request stgin.RequestContext) stgin.Status {...}

// but using functions is more convenient and is recommended
// or inline the implementation in route definition #not recommended

Fine for now, let's create the controller in /health/init.go. It's better to use init to initialize controllers and apis.

// health/init.go file

package health

import "github.com/AminMal/stgin"

var Controller *stgin.Controller // exposed to main package

func init() {
    Controller = stgin.NewController("HealthController", "/health")
    Controller.AddRoutes(
      stgin.GET("/status", getHealthAPI), // defined in apis.go
      // this route will be interpreted to /health/status
    )
}

So the health APIs are implemented, let's integrate them into the server. Now in the root directory of the project, let's open init.go file.

package main

import "github.com/AminMal/stgin"
import "fmt"

var server *stgin.Server

func init() {
        portNo := 9000
        server = stgin.DefaultServer(fmt.Sprintf(":%d", portNo))
        // default server included default logger and error handler
        server.Register(health.Controller)
}

Almost done, let's just run the server (main.go).

package main

import "log"

func main() {
        log.Fatal(server.Start()) // all done
}

Your application will be up and running.

Another approach to define routes is route builder. You might want to use some method which is not defined in stgin default routing methods. You can use:

stgin.OnPattern("/your/path/$path_param").WithMethod("something").Do(
        func(req stgin.RequestContext) stgin.Status{...},
)

A comparison between stgin and gin-gonic, writing a simple API:

// Given response type as
type HealthCheckResponse struct {
        DBConnection    bool    `json:"database_connection"`
        Message         string  `json:"message"`
}
// and request type as
type HealthCheckRequest struct {
        Whatever        string   `json:"whatever"`
}

stgin implementation:

health := stgin.POST("/health", func(request stgin.RequestContext) stgin.Status {
    var reqBody HealthCheckRequest
    request.Body().JSONInto(&reqBody)
    // do something with reqBody
    var response HealthCheckResponse = GetHealth()
    if response.DBConnection {
        return stgin.Ok(stgin.Json(&response)) 
    } else {
        return stgin.InternalServerError(stgin.Json(&response))
    }
})

gin implementation:

r.POST("/health", func(c *framework.Context) {
    var reqBody HealthCheckRequest
    bodyBytes, err := ioutil.ReadAll(c.Request.Body)
    if err != nil {
        // potential error handling
    }
    err = json.Unmarshal(bodyBytes, &reqBody)
    if err != nil {
        // potential error handling
    }
        // do something with reqBody
    var response HealthCheckResponse = GetHealth()
    jsonResponse, _ := json.Marshal(response)
    if response.DBConnection {
        _, writeError := c.Writer.Write(jsonResponse)
        c.Status(200)
        if writeError != nil {
            // potential error handling
        }
    } else {
        c.Status(500)
        _, writeError = c.Writer.Write(jsonResponse)
        if writeError != nil {
            // potential error handling
        }
    }
})

Or just easily add headers or cookies with a receiver function instead of manually writing:

stgin.Ok(...).
      WithHeaders(...).
      WithCookies(...)

Structure

The structure of stgin types and interfaces is pretty simple, a Server may have several Controllers, and each controller may have serveral Routes.

    
    -Server =>
        -Controller 1 ->
            -Route 1 (path pattern, method, api)
            -Route 2 (path pattern, method, api)
        -Cotroller 2 ->
            -Route 1 (path pattern, method, api)

Server: Is run on the specified port, contains the controllers.

Controller: Contains routes which are exposed to the server, has a name, and may have a route prefix (i.e., /home)

Route: Holds route specifications (i.e., method, path, API action)

RequestContext: Holds the information about the requests, such as uri, body, headers, ... . Can parse request entity into the desired variable, using helper functions like request.JSONInto, request.XMLInto.

Status: Is a wrapper around an actual http response, holds status code, response headers, response body, ... (i.e., Ok, BadRequest, ...)

  • ResponseEntity: A response could be of different content types (i.e., JSON, XML, Text, file, ...). A response entity is an interface which defines the content type of the response, and entity bytes. There are some helper functions provided in stgin to ease the use of these entities, like stgin.Json, stgin.Text, stgin.Xml, stgin.File.

API: Is a type alias for a function which accepts a request context and returns a status.

Path Parameters

  • How to define?

    When defining a route, there are 2 possible values between any 2 slashes, a literal string (like ".../home/..."), or a path parameter specification. Path parameters must have a name, and an optional type which the parameter might have (string is used as default, if no type or an invalid type is provided).

            //same as $username:string
    stgin.GET("/users/$username/purchases/$purchase_id:int". ...)
    
    // "/users/$username/purchases/$purchase_id" also accepts the correct route like "/users/John/purchases/12",
    // but in case an alphanumeric value is passed as purchase_id, conversion from string to int in the api is manual
    // and needs manual error checking
    
  • How to get?

    username, exists := request.PathParams.Get("username")
    // or if you're sure about the existence, 
    username := request.PathParams.MustGet("username")
    // or if you have specified the type in path pattern
    purchaseId := request.PathParams.MustGetInt("purchase_id")
    // or
    purchaseId, err := request.PathParams.GetInt("purchase_id")
    

Query Parameters

  • When to define?

    Define query parameter specifications only for mandatory and non-empty query parameter expectations.

  • How to define?

    When defining a route, you can specify which query params of what type the route should expect. If a request could not satisfy the expected queries, it will be rejected by the route and will be passed into the next route and so on. Specifying query parameters does not mean that the route will not accept other query parameters which are not specified. By specifying the query parameters, you just make sure that when a request is accepted by the route, it always contains those query parameters with the right type. After defining the path pattern, use a question mark ? to start defining query parameters, write the name of the parameter (if it has a certain type, use : and put the type name, i.e., int, string, float), and when done, put & to define the next query parameter. The order of queries does not matter.

      stgin.GET("/users?username&id:int")
      // Just like path parameters, if you do not specify the type of query, it's assumed to be string, 
      // so "username" here is interpreted into "username:string" 
    

    As mentioned earlier, this pattern will match urls like /users?id=7&username=JohnDoe&otherquery=whatever&anotherone=true. And you can access those easily in the request, so no worries about not specifying all the query parameters.

  • How to get?

    Just like path parameters, query parameters follow the same rules for receiver functions.

      userId := request.QueryParams.MustGetInt("user_id")
      // so on, just like path parameters
    
  • Query to object

    There is a special method in request context, which can convert queries into a struct object. There are some few notes to take before using this. When defining the expected struct that the queries will be converted into, if you need to use other naming in queries rather than the field name in struct, use qp (short for query parameter) tag to specify the name (just like json tag):

      type UserSearchFilter struct {
          Username   string  `qp:"name"`
          Id         int     `qp:"id"`
          Joined     string  
      }
    
    • Always pass pointers to the function
    • Non-exported fields will not be parsed from request query parameters
    • If you do not pass the name to qp tag, parser would look up for the actual field name in the queries: Notice the Joined field in the struct, parser looks for &Joined=... in the url.

Custom parameter patterns

stgin provides patterns for int, string, float and uuid already. but If you need to add some custom pattern to use in query or path parameter definition, you can add the name with a valid pattern(regex) that gets compiled.

startsWithJohnRegex := "^john.*"
err := AddMatchingPattern("john", startsWithJohnRegex)

the above function will fail with errors if:

    1. Try to override default patterns (int, string, float, uuid)
    1. The given pattern couldn't be compiled

Custom Actions

stgin does not provide actions about stuff like Authentication, because simple authentication is not useful most of the time, and you may need customized authentications.

For instance:

type AuthInfo struct {
        Username    string      `json:"username"`
        AccountId   int         `json:"account_id"`
        Roles       []string    `json:"roles"`
}

func authenticate(rc stgin.RequestContext) (AuthInfo, bool) {
    if name, found := rc.QueryParams.Get("user"); !found {
        ...
    } else {
        ...
    }
}

func Authenticated(rc stgin.RequestContext, action func(AuthInfo) stgin.Status) stgin.Status {
    authInfo, isAuthenticated := authenticate(rc)
    if !isAuthenticated {
        return stgin.Unauthorized(...)
    } else {
        return action(authInfo)
    }
}

// In the apis section
myAPI := stgin.GET("/test", func(request stgin.RequestContext) stgin.Status {
    return Authenticated(request, func(authInfo AuthInfo) stgin.Status {
        return stgin.Ok(stgin.Json(&Greet(authInfo.Username)))
    })
})

Listeners

Listeners are functions, which can affect the request and response based on the defined behavior. For instance, a ResponseListener is a function which receives a response, and returns a response, it can be used when you want to apply something to all the responses in server layer or controller layer (i.e., providing CORS headers). There are 3 types of listeners:

  • RequestListener: RequestContext => RequestContext [Can be used to return a new modified instance of the request]

      func AddUserTrackingKey(request stgin.RequestContext) stgin.RequestContext {
        request.Headers["X-Tracking-Key"] = []string{"some-generated-header"}
        return request
      }
    
  • ResponseListener: Status => Status [Can be used to add/remove additional information to a new instance of Status]

      func AddUserKeyToResponse(response stgin.Status) stgin.Status {
        return response.WithHeaders(http.Header{"X-Tracking-Key": {"<Some random value>"}}
      }
    
  • APIListener: (RequestContext, Status) => void [Can be used to do stuff like logging, ...]

      func ApiLogger(request stgin.RequestContext, response stgin.Status) {
        fmt.Println("received", request, "returned", response)
      }
    

    There are some listeners provided inside the stgin package which can be used inside a server or a controller (API watcher/logger, recovery, they're used in stgin.DefaultServer as well).

CORS Handling

Cors handling can be done using server APIs:

server.CorsHandler(stgin.CorsHandler{
        AllowOrigin: []string{"first_host.com", "second_host.com"},
        AllowHeaders: []string{"*"},
        AllowMethods: []string{"GET", "PUT", "POST", "HEAD", "OPTIONS"},
        ...
})

Timeout

You can adjust server request timeout using server.SetTimeout, this way if the request processing takes longer than the specified timeout, the server will automatically abort the request and complete with a 408 request timed out response.

Custom Recovery

An ErrorHandler can be provided by the developer, to provide custom error handling behavior. Definition of an ErrorHandler function is pretty straight forward, you just define a function which takes the request and the error, and decides what to return as the status.

var myErrorHandler stgin.ErrorHandler = func(request RequestContext, err any) stgin.Status {
    if myCustomErr, isCustomErr := err.(CustomErr); isCustomErr {
        return stgin.BadRequest(...)
    } else {
        return stgin.InternalServerError(...)
    }
}

Files And Directories

Files:

Working with files and directories is pretty easy. They are dealt just as normal response entities. They have a content type depending on the file format, and file bytes. So you can return them inside your APIs, just give stgin the file location. If the file could not be found, 404 not found is returned to the client as the response, and if there was some problems reading the file, 500 internal server error would be returned.

Directories:

Directories are a bit out of RESTful APIs concept, so It's not possible in stgin to return them as an http response. Instead of defining routes for the file system, a special Routing function is available as StaticDir:

SomeController.AddRoutes(...) // some routes
SomeController.AddRoutes(
    stgin.GET("/some/pattern", someAPI),
    stgin.StaticDir("/get_my_files", "/tmp"),
    // serves /tmp folder on "</controller_prefix_if_exists>/get_my_files"
)

Http 2 Push

Http push is available if you're using go 1.18 above, and using http 2 as a communication protocol.

// inside api definiction
if request.HttpPush.IsSupported {
        pusher := request.HttpPush.Pusher
        // do stuff with pusher
}

Html Templates

STgin does not support "rendering" html templates (parsing and creating appropriate sources for images, etc. developers should take care of images), but loading html templates using variables is supported.

  • Template variables: To define template variables, wrap the variable name inside double curly braces. (i.e., {{ title }}, {{name}}, spaces are ignored).
//    /
//    /templates
//      welcome.html
//      /images
stgin.GET("/welcome", func (request stgin.RequestContext) stgin.Status {
    return stgin.Ok(template.LoadTemplate("./templates/welcome.html", template.Variables{
        "title": "Welcome to the team",
        "name": "John Doe",
}))
})

WIP

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddMatchingPattern added in v1.1.1

func AddMatchingPattern(key string, rawPattern string) error

func Prefix added in v0.4.6

func Prefix(path string) string

Prefix can be used as a pattern inside route definition, which matches all the requests that contain the given prefix. Note that this is appended to the corresponding controller's prefix in which the route is defined.

func WatchAPIs

func WatchAPIs(request RequestContext, status Status)

WatchAPIs is the default request and response logger for stgin. It logs the input request and the output response into the console.

Types

type API

type API = func(c RequestContext) Status

API is the lowest-level functionality in stgin. It represents a function which takes a request, and generates an HTTP response.

type APIListener added in v0.2.3

type APIListener = func(RequestContext, Status)

APIListener is a function which is applied to both request and response, after the response is written to the client. It can be defined both on the controller layer, or server layer.

type Controller

type Controller struct {
	Name string
	// contains filtered or unexported fields
}

Controller is a struct which groups some routes, and may have a path prefix. And might hold some request/response/api listeners.

func NewController

func NewController(name string, prefix string) *Controller

NewController returns a pointer to a newly created controller with the given name and path prefixes.

func (*Controller) AddAPIListeners added in v0.2.3

func (controller *Controller) AddAPIListeners(listeners ...APIListener)

AddAPIListeners registers the given listeners to the controller. These listeners then will be applied to all the incoming/outgoing requests and responses after they're evaluated And returned to the client.

func (*Controller) AddRequestListeners

func (controller *Controller) AddRequestListeners(listeners ...RequestListener)

AddRequestListeners registers the given listeners to the controller. These listeners then will be applied to all the requests coming inside this controller.

func (*Controller) AddResponseListener

func (controller *Controller) AddResponseListener(listeners ...ResponseListener)

AddResponseListener registers the given listeners to the controller. These listeners then will be applied to all the outgoing responses from this controller.

func (*Controller) AddRoutes

func (controller *Controller) AddRoutes(routes ...Route)

AddRoutes normalizes, and evaluates path matchers for the given routes, and then adds them to the routes it contains.

func (*Controller) RegisterInterrupts added in v0.6.3

func (controller *Controller) RegisterInterrupts(interrupts ...Interrupt)

RegisterInterrupts adds the given interrupts to the controller's already existing interrupts.

func (*Controller) SetTimeout added in v0.6.3

func (controller *Controller) SetTimeout(timeout time.Duration)

SetTimeout registers a timeout interrupt into the controller.

type CorsHandler added in v0.5.4

type CorsHandler struct {
	AllowOrigin      []string
	AllowCredentials []string
	AllowHeaders     []string
	AllowMethods     []string
}

CorsHandler is just a semantic wrapper over common CORS headers.

type ErrorHandler added in v0.2.4

type ErrorHandler = func(request RequestContext, err any) Status

ErrorHandler is a function which can decide what to do, based on the request and the error.

type Interrupt added in v0.6.3

type Interrupt interface {
	TriggerFor(request RequestContext, completeWith chan *Status)
}

Interrupt is n abstract semantic, that can be executed along-side the request, And if some event happens, can abort the request and complete with another response, which is filled within completeWith. A real world example would be timeouts; server.SetTimeout actually uses an interrupt to perform timeout operations.

func TimeoutInterrupt added in v0.6.3

func TimeoutInterrupt(timeout time.Duration) Interrupt

type MalformedRequestContext added in v0.2.5

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

func (MalformedRequestContext) Error added in v0.2.5

func (mrc MalformedRequestContext) Error() string

type Params added in v0.2.6

type Params = map[string]string

type ParseError added in v0.2.5

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

func (ParseError) Error added in v0.2.5

func (ije ParseError) Error() string

type PathParams added in v0.5.9

type PathParams struct {
	All map[string]string
}

PathParams is a struct wrapped around the path parameters of an HTTP request. It provides some receiver functions which make it easier than ever to use them.

func (PathParams) Get added in v0.5.9

func (pp PathParams) Get(key string) (string, bool)

Get tries to find a path parameter by the given key.

func (PathParams) GetFloat added in v0.5.9

func (pp PathParams) GetFloat(key string) (float64, error)

GetFloat tries to find a path parameter by the given key, and tries to convert it to float. In case any error happens from finding to converting, this function returns immediately.

func (PathParams) GetInt added in v0.5.9

func (pp PathParams) GetInt(key string) (int, error)

GetInt tries to find a path parameter by the given key, and tries to convert it to integer. In case any error happens from finding to converting, this function returns immediately.

func (PathParams) MustGet added in v0.5.9

func (pp PathParams) MustGet(key string) string

MustGet tries to find a path parameter by the given key. Returns empty string in case it couldn't be found.

func (PathParams) MustGetFloat added in v0.5.9

func (pp PathParams) MustGetFloat(key string) float64

MustGetFloat tries to find a path parameter by the given key, and tries to convert it to float. This function should be used when you have defined your path parameter to be floating point inside the route pattern (like "/geo/$lat:float"). This function will panic in case of any error.

func (PathParams) MustGetInt added in v0.5.9

func (pp PathParams) MustGetInt(key string) int

MustGetInt tries to find a path parameter by the given key, and tries to convert it to integer. This function should be used when you have defined your path parameter to be integer inside the route pattern (like "/users/$id:int"). This function will panic in case of any error.

type Push added in v0.4.5

type Push struct {
	IsSupported bool
	// contains filtered or unexported fields
}

Push is a struct that represents both the ability, and the functionality of http push inside this request.

func (Push) Pusher added in v0.4.5

func (p Push) Pusher() http.Pusher

Pusher returns the actual http.Pusher instance, only if it's supported. Note that this will panic if it's not supported, so make sure to use IsSupported field before calling this function.

type Queries added in v0.5.9

type Queries struct {
	All map[string][]string
}

Queries is just a struct holding all the key value pairs of request's query parameters. It also defines some useful receiver functions in order to ease fetching query params.

func (Queries) Get added in v0.5.9

func (q Queries) Get(key string) ([]string, bool)

Get looks for the given key in all queries, and returns the value if it exists.

func (Queries) GetFloat added in v0.5.9

func (q Queries) GetFloat(key string) (float64, error)

GetFloat is the same as Get, but when you have defined query type to be floating point inside the route pattern. In case of any error from finding to converting, the error is returned immediately.

func (Queries) GetInt added in v0.5.9

func (q Queries) GetInt(key string) (int, error)

GetInt is the same as Get, but when you have defined query type to be integer inside the route pattern. In case of any error from finding to converting, the error is returned immediately.

func (Queries) GetOne added in v0.5.9

func (q Queries) GetOne(key string) (string, bool)

GetOne is used when you're sure if one and only one value exists for the given query.

func (Queries) MustGet added in v0.5.9

func (q Queries) MustGet(key string) string

MustGet can be used when you're sure about the existence of a key in query parameters. It panics in it has 0 or more than 1 values.

func (Queries) MustGetFloat added in v0.5.9

func (q Queries) MustGetFloat(key string) float64

MustGetFloat is the same as MustGet, but when you have defined query type to be floating point inside the route pattern. It panics in case of any error from finding to converting the value to float.

func (Queries) MustGetInt added in v0.5.9

func (q Queries) MustGetInt(key string) int

MustGetInt is the same as MustGet, but when you have defined query type to be integer inside the route pattern. It panics in case of any error from finding to converting the value to int.

type RequestBody

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

RequestBody holds the bytes of the request's body entity.

func (*RequestBody) JSONInto added in v0.2.5

func (body *RequestBody) JSONInto(a any)

JSONInto receives a pointer to anything, and will try to parse the request's JSON entity into it. It panics in case any error happens.

func (*RequestBody) SafeJSONInto added in v0.2.5

func (body *RequestBody) SafeJSONInto(a any) error

SafeJSONInto receives a pointer to anything, and will try to parse the request bytes into it as JSON. if any error occurs, it is returned immediately by the function.

func (*RequestBody) SafeXMLInto added in v0.2.5

func (body *RequestBody) SafeXMLInto(a any) error

SafeXMLInto receives a pointer to anything, and will try to parse the request bytes into it as JSON. if any error occurs, it is returned immediately by the function.

func (*RequestBody) XMLInto added in v0.2.5

func (body *RequestBody) XMLInto(a any)

XMLInto receives a pointer to anything, and will try to parse the request's XML entity into it. It panics in case any error happens.

type RequestContext

type RequestContext struct {
	Url         string
	QueryParams Queries
	PathParams  PathParams
	Headers     http.Header
	Trailer     http.Header
	Body        func() *RequestBody

	Method        string
	ContentLength int64
	Host          string
	MultipartForm func() *multipart.Form
	Scheme        string
	RemoteAddr    string
	Underlying    *http.Request
	HttpPush      Push
	// contains filtered or unexported fields
}

RequestContext holds all the information about incoming http requests.

func (RequestContext) AddCookie added in v0.4.1

func (request RequestContext) AddCookie(cookie *http.Cookie)

AddCookie adds the cookie to the request.

func (RequestContext) Cookie added in v0.4.1

func (request RequestContext) Cookie(name string) (*http.Cookie, error)

Cookie tries to find a cookie with the given name.

func (RequestContext) Cookies added in v0.4.1

func (request RequestContext) Cookies() []*http.Cookie

Cookies returns the cookies that are attached to the request.

func (RequestContext) Form added in v0.5.5

func (request RequestContext) Form() (map[string][]string, error)

Form returns all the key-values inside the given request. It calls ParseForm itself.

func (RequestContext) FormFile added in v0.5.5

func (request RequestContext) FormFile(key string) (multipart.File, *multipart.FileHeader, error)

FormFile is a shortcut to get a file with the given name from multipart form.

func (RequestContext) FormValue added in v0.5.5

func (request RequestContext) FormValue(key string) string

FormValue is a shortcut to get a value by name inside the request form instead of parsing the whole form.

func (RequestContext) ParseMultipartForm added in v0.5.5

func (request RequestContext) ParseMultipartForm(maxMemory int64) error

ParseMultipartForm is the manual approach to parse the request's entity to multipart form. Please read (*http.Request).ParseMultipartForm for more detailed information.

func (RequestContext) PostForm added in v0.5.5

func (request RequestContext) PostForm() (map[string][]string, error)

PostForm returns all the key-values inside the given request's post-form.

func (RequestContext) PostFormValue added in v0.5.5

func (request RequestContext) PostFormValue(key string) string

PostFormValue can get a value by the given name from request post-form.

func (RequestContext) QueryToObj added in v0.5.4

func (request RequestContext) QueryToObj(a any) error

QueryToObj receives a pointer to a struct, and tries to parse the query params into it. Please read the documentations [here](https://github.com/AminMal/stgin#query-parameters) for more details.

func (RequestContext) ReceivedAt added in v0.6.2

func (request RequestContext) ReceivedAt() time.Time

func (RequestContext) Referer added in v0.5.5

func (request RequestContext) Referer() string

Referer returns the value of referer header in http request, returns empty string if it does not exist.

func (RequestContext) UserAgent added in v0.5.5

func (request RequestContext) UserAgent() string

UserAgent returns the value of request's user agent, returns empty string if it does not exist.

type RequestListener

type RequestListener = func(RequestContext) RequestContext

RequestListener is a function which is applied to the incoming requests, before the api actually receives it. It can be defined both on the controller layer, or server layer.

type ResponseEntity added in v0.4.1

type ResponseEntity interface {
	// ContentType represents *HTTP* response content type of the entity.
	ContentType() string
	// Bytes function is responsible to provide response entity bytes, and eny error if exists.
	Bytes() ([]byte, error)
}
	ResponseEntity is an interface representing anything that can be sent through http response body.
	Structs implementing ResponseEntity must have a content type (which is written directly in the response),
	And also a function which can provide entity bytes, or any error if exists.
	So for instance if you wanted to define a custom PDF ResponseEntity (which is already supported using File function),

	type PDF struct {
        filepath string
    }
	func (pdf PDF) ContentType() string { return "application/pdf" }
	func (pdf PDF) Bytes() ([]byte, error) { ... read file ... }

	And simply use it inside your APIs.

	return stgin.Ok(PDF{filePath})

func Empty added in v0.5.4

func Empty() ResponseEntity

Empty is used when you want to return empty responses to the client. There are situations where status codes talk, and there is no need to populate response body with non-meaningful data.

func Json added in v0.4.1

func Json(a any) ResponseEntity

Json is a shortcut to convert any object into a JSON ResponseEntity.

func Text added in v0.4.1

func Text(text string) ResponseEntity

Text is a shortcut to convert any object into a text ResponseEntity.

func Xml added in v0.4.1

func Xml(a any) ResponseEntity

Xml is a shortcut to convert any object into an XML ResponseEntity.

type ResponseListener

type ResponseListener = func(Status) Status

ResponseListener is a function which is applied to the outgoing http responses, after they're evaluated by the api. It can be defined both on the controller layer, or server layer.

type Route

type Route struct {
	Path   string
	Method string
	Action API
	// contains filtered or unexported fields
}

Route is a struct which specifies whether a request should be handled by the given Action inside the route.

func DELETE

func DELETE(pattern string, api API) Route

DELETE is a shortcut to define a route with http "DELETE" method.

func GET

func GET(pattern string, api API) Route

GET is a shortcut to define a route with http "GET" method.

func Handle added in v0.4.4

func Handle(method string, pattern string, api API) Route

Handle is a generic function that can be used for other http methods that do not have a helper function in stgin (like GET).

func OPTIONS added in v0.2.2

func OPTIONS(pattern string, api API) Route

OPTIONS is a shortcut to define a route with http "OPTIONS" method.

func PATCH

func PATCH(pattern string, api API) Route

PATCH is a shortcut to define a route with http "PATCH" method.

func POST

func POST(pattern string, api API) Route

POST is a shortcut to define a route with http "POST" method.

func PUT

func PUT(pattern string, api API) Route

PUT is a shortcut to define a route with http "PUT" method.

func StaticDir added in v0.4.8

func StaticDir(pattern string, dir string) Route

StaticDir can be used to server static directories. It's better to use StaticDir inside the server itself, or to have a dedicated controller for static directories you would want to serve.

type RouteCreationStage

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

RouteCreationStage is a struct that can make routes step by step. Is only returned after OnPath function is called.

func OnPath

func OnPath(path string) RouteCreationStage

OnPath is the starting point of route creation stage, specifies the pattern.

func (RouteCreationStage) Do

func (stage RouteCreationStage) Do(api API) Route

Do assign's the api action to the route creation stage, and returns the resulting route.

func (RouteCreationStage) WithMethod

func (stage RouteCreationStage) WithMethod(method string) RouteCreationStage

WithMethod attaches the method to the route creation stage.

type Server

type Server struct {
	Controllers []*Controller
	// contains filtered or unexported fields
}

Server is the starting point of stgin applications, which holds the address, controllers, APIs and server-level listeners. Which can be run on the specified address.

func DefaultServer added in v0.4.1

func DefaultServer(addr string) *Server

DefaultServer is the recommended approach to get a new Server. It includes error handler and api logger by default.

func NewServer

func NewServer(addr string) *Server

NewServer returns a pointer to a basic stgin Server.

func (*Server) AddAPIListeners added in v0.2.3

func (server *Server) AddAPIListeners(listeners ...APIListener)

AddAPIListeners adds the given api listeners to server-level listeners (which then will be applied to all the incoming requests and outgoing responses after they're finished).

func (*Server) AddRequestListeners

func (server *Server) AddRequestListeners(listeners ...RequestListener)

AddRequestListeners adds the given request listeners to server-level listeners (which then will be applied to all the incoming requests).

func (*Server) AddResponseListeners

func (server *Server) AddResponseListeners(listeners ...ResponseListener)

AddResponseListeners adds the given response listeners to server-level listeners (which then will be applied to all the outgoing responses).

func (*Server) AddRoutes added in v0.5.2

func (server *Server) AddRoutes(routes ...Route)

AddRoutes is an alternative to controller.AddRoutes, which adds the given routes to the server's default controller.

func (*Server) CorsHandler added in v0.5.4

func (server *Server) CorsHandler(handler CorsHandler)

CorsHandler function takes the responsibility to handle requests with "OPTIONS" method with the given headers in handler parameter.

func (*Server) HttpHandler added in v0.7.1

func (server *Server) HttpHandler() http.Handler

func (*Server) NotFoundAction added in v0.2.2

func (server *Server) NotFoundAction(action API)

NotFoundAction defines what server should do with the requests that match no routes.

func (*Server) Register

func (server *Server) Register(controllers ...*Controller)

Register appends given controllers to the server.

func (*Server) RegisterInterrupts added in v0.6.3

func (server *Server) RegisterInterrupts(interrupts ...Interrupt)

RegisterInterrupts adds the given interrupts to the server's already existing interrupts

func (*Server) SetErrorHandler added in v0.2.5

func (server *Server) SetErrorHandler(action ErrorHandler)

SetErrorHandler defines what server should do in case some api panics.

func (*Server) SetTimeout added in v0.6.1

func (server *Server) SetTimeout(dur time.Duration)

SetTimeout registers a timeout interrupt to the server

func (*Server) Start

func (server *Server) Start() error

Start executes the server over the specified address. In case any uncaught error or panic happens, and is not recovered in the server's error handler, the error value is returned as a result.

type Status

type Status struct {
	StatusCode int
	Entity     ResponseEntity
	Headers    http.Header
	// contains filtered or unexported fields
}

Status is the return type of stgin APIs. It represents an HTTP response with a status code, headers, body and cookies.

func BadRequest

func BadRequest(body ResponseEntity) Status

BadRequest represents a basic http 400 response with the given body.

func CreateResponse

func CreateResponse(statusCode int, body ResponseEntity) Status

CreateResponse can be used in order to make responses that are not available in default functions in stgin. For instance a 202 http response.

func Created

func Created(body ResponseEntity) Status

Created represents a basic http 201 response with the given body.

func File added in v0.4.5

func File(path string) Status

File is used to return a file itself as an HTTP response. If the file is not found, it returns 404 not found to the client. If there are issues reading file or anything else related, 500 internal server error is returned to the client.

func Forbidden

func Forbidden(body ResponseEntity) Status

Forbidden represents a basic http 403 response with the given body.

func Found

func Found(location string) Status

Found represents a basic http 302 redirect to the given location.

func InternalServerError

func InternalServerError(body ResponseEntity) Status

InternalServerError represents a basic http 500 response with the given body.

func MethodNotAllowed added in v0.2.2

func MethodNotAllowed(body ResponseEntity) Status

MethodNotAllowed represents a basic http 405 response with the given body.

func MovedPermanently

func MovedPermanently(location string) Status

MovedPermanently represents a basic http 301 redirect to the given location.

func NotFound

func NotFound(body ResponseEntity) Status

NotFound represents a basic http 404 response with the given body.

func Ok

func Ok(body ResponseEntity) Status

Ok represents a basic http 200 response with the given body.

func PermanentRedirect

func PermanentRedirect(location string) Status

PermanentRedirect represents a basic http 308 redirect to the given location.

func Unauthorized

func Unauthorized(body ResponseEntity) Status

Unauthorized represents a basic http 401 response with the given body.

func (Status) DoneAt added in v0.6.2

func (status Status) DoneAt() time.Time

func (Status) WithCookies added in v0.4.1

func (status Status) WithCookies(cookies ...*http.Cookie) Status

WithCookies returns a new Status, appended the given cookies.

func (Status) WithHeaders

func (status Status) WithHeaders(headers http.Header) Status

WithHeaders returns a new Status, appended the given headers.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL