cherry

package module
v0.0.0-...-621f9a0 Latest Latest
Warning

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

Go to latest
Published: Jan 27, 2024 License: MIT Imports: 20 Imported by: 0

README

Cherry🍒 Go

🚨Cherry🍒 is a web framework for Go language.

Installation

go get github.com/pooulad/cherry

Features

  • fast route dispatching backed by http-router
  • easy to add middleware handlers
  • sub-routing with separated middleware handlers
  • central based error handling
  • build in template engine
  • fast, lightweight and extendable

Basic usage

package main
import "github.com/pooulad/cherry"

func main() {
    app := cherry.New()

    app.Get("/foo", fooHandler)
    app.Post("/bar", barHandler)
    app.Use(middleware1, middleware2)

    friends := app.Group("/friends")
    friends.Get("/profile", profileHandler)
    friends.Use(middleware3, middleware4)
    
    app.Serve(8080)
}

More complete examples can be found in the examples folder

Routes

app := cherry.New()

app.Get("/", func(ctx *cherry.Context) error {
   .. do something .. 
})
app.Post("/", func(ctx *cherry.Context) error {
   .. do something .. 
})
app.Put("/", func(ctx *cherry.Context) error {
   .. do something .. 
})
app.Delete("/", func(ctx *cherry.Context) error {
   .. do something .. 
})

get named url parameters

app.Get("/hello/:name", func(ctx *cherry.Context) error {
    name := ctx.Param("name")
})

Group (subrouting)

Group lets you manage routes, contexts and middleware separate from each other.

Create a new cherry object and attach some middleware and context to it.

app := cherry.New()
app.BindContext(context.WithValue(context.Background(), "foo", "bar")
app.Get("/", somHandler)
app.Use(middleware1, middleware2)

Create a group and attach its own middleware and context to it

friends := app.Group("/friends")
app.BindContext(context.WithValue(context.Background(), "friend1", "john")
friends.Post("/create", someHandler)
friends.Use(middleware3, middleware4)

In this case group friends will inherit middleware1 and middleware2 from its parent app. We can reset the middleware from its parent by calling Reset()

friends := app.Group("/friends").Reset()
friends.Use(middleware3, middleware4)

Now group friends will have only middleware3 and middleware4 attached.

Static files

Make our assets are accessible trough /assets/styles.css

app := cherry.New()
app.Static("/assets", "public/assets")

Handlers

A definition of a cherry.Handler
func(ctx *cherry.Context) error

Cherry only accepts handlers of type cherry.Handler to be passed as functions in routes. You can convert any type of handler to a cherry.Handler.

func myHandler(name string) cherry.Handler{
    .. do something ..
   return func(ctx *cherry.Context) error {
        return ctx.Text(w, http.StatusOK, name)
   }
}
Returning errors

Each handler requires an error to be returned. This is personal idiom but it brings some benefits for handling your errors inside request handlers.

func someHandler(ctx *cherry.Context) error {
    // simple error handling by returning all errors 
    err := someFunc(); err != nil {
        return err
    }
    ...
    req, err := http.NewRequest(...)
    if err != nil {
        return err
    }
}

A cherry ErrorHandlerFunc

func(ctx *cherry.Context, err error)

Handle all errors returned by adding a custom errorHandler for our application.

app := cherry.New()
errHandler := func(ctx *cherry.Context, err error) {
    .. handle the error ..
}
app.SetErrorHandler(errHandler)

Context

Context is a request based object helping you with a series of functions performed against the current request scope.

Passing values around middleware functions

Context provides a context.Context for passing request scoped values around middleware functions.

Create a new context and pass some values

func someMiddleware(ctx *cherry.Context) error {
    ctx.Context = context.WithValue(ctx.Context, "foo", "bar")
    return someMiddleware2(ctx)
}

Get the value back from the context in another middleware function

func someMiddleware2(ctx *cherry.Context) error {
    value := ctx.Context.Value("foo").(string)
    ..
}
Binding a context

In some cases you want to initialize a context from the the main function, like a datastore for example. You can set a context out of a request scope by calling BindContext().

app.BindContext(context.WithValue(context.Background(), "foo", "bar"))

As mentioned in the Group section, you can add different contexts to different groups.

myGroup := app.Group("/foo", ..)
myGroup.BindContext(..)
Helper functions

Context also provides a series of helper functions like responding JSON en text, JSON decoding etc..

func createUser(ctx *cherry.Context) error {
    user := model.User{}
    if err := ctx.DecodeJSON(&user); err != nil {
        return errors.New("failed to decode the response body")
    }
    ..
    return ctx.JSON(http.StatusCreated, user)
}

func login(ctx *cherry.Context) error {
    token := ctx.Header("x-hmac-token")
    if token == "" {
        ctx.Redirect("/login", http.StatusMovedPermanently)
        return nil
    }
    ..
}

Logging

Access Log

Cherry provides an access-log in an Apache log format for each incoming request. The access-log is disabled by default, to enable the access-log set app.HasAccessLog = true.

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

Server

Cherry HTTP server is a wrapper around the default std HTTP server, the only difference is that it provides a graceful shutdown. Cherry provides both HTTP and HTTPS (TLS).

app := cherry.New()
app.ServeTLS(8080, cert, key)
// or 
app.Serve(8080)
Gracefull stopping a cherry app

Gracefull stopping a cherry app is done by sending one of these signals to the process.

  • SIGINT
  • SIGQUIT
  • SIGTERM

You can also force-quit your app by sending it SIGKILL signal

SIGUSR2 signal is not yet implemented. Reloading a new binary by forking the main process is something that wil be implemented when the need for it is there. Feel free to give some feedback on this feature if you think it can provide a bonus to the package.

Screenshots

App Screenshot

App Screenshot

Support

If you like Cherry🍒 buy me a coffee☕ or star project🌟

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cherry

type Cherry struct {
	ErrorHandler ErrorHandlerFunc

	// Output writes the access-log and debug parameters for web-server
	Output io.Writer

	// HasAccessLog enables access-log for cherry. The default is false
	HasAccessLog bool

	// HTTP2 enables the HTTP2 protocol on the server(TLS)
	HTTP2 bool
	// contains filtered or unexported fields
}

Cherry is a web framework for making fast and simple web applications in the Go programming language. Cherry supports by one of the fastest request router in Golang. It is also provides a graceful web server that can serve TLS encrypted requests as well.

func New

func New() *Cherry

New returns a new Cherry object.

func (*Cherry) BindContext

func (c *Cherry) BindContext(ctx context.Context)

BindContext lets you provide a context that will live a full http roundtrip BindContext is mostly used in a func main() to provide init variables that may be created only once, like a database connection. If BindContext is not called, Cherry will use a context.Background().

func (*Cherry) Delete

func (c *Cherry) Delete(route string, h Handler)

Delete invokes when request method in handler is set to DELETE.

func (*Cherry) Get

func (c *Cherry) Get(route string, h Handler)

Get invokes when request method in handler is set to GET.

func (*Cherry) Group

func (c *Cherry) Group(prefix string) *Group

Group returns a new Group that will inherit all of its parents middleware. you can reset the middleware registered to the group by calling Reset().

func (*Cherry) Handle

func (c *Cherry) Handle(method, path string, h http.Handler)

Handle adapts the usage of an http.Handler and will be invoked when the router matches the prefix and request method.

func (*Cherry) Head

func (c *Cherry) Head(route string, h Handler)

Head invokes when request method in handler is set to HEAD.

func (*Cherry) Options

func (c *Cherry) Options(route string, h Handler)

Options invokes when request method in handler is set to OPTIONS.

func (*Cherry) Post

func (c *Cherry) Post(route string, h Handler)

Post invokes when request method in handler is set to POST.

func (*Cherry) Put

func (c *Cherry) Put(route string, h Handler)

Put invokes when request method in handler is set to PUT.

func (*Cherry) Serve

func (c *Cherry) Serve(port int) error

Serve method serves the cherry web server on the given port.

func (*Cherry) ServeCustom

func (c *Cherry) ServeCustom(s *http.Server) error

ServeCustom method serves the application with custom server configuration.

func (*Cherry) ServeCustomTLS

func (c *Cherry) ServeCustomTLS(s *http.Server, certFile, keyFile string) error

ServeCustomTLS method serves the application with TLS encryption and custom server configuration.

func (*Cherry) ServeHTTP

func (c *Cherry) ServeHTTP(rw http.ResponseWriter, r *http.Request)

ServeHTTP satisfies the http.Handler interface.

func (*Cherry) ServeTLS

func (c *Cherry) ServeTLS(port int, certFile, keyFile string) error

ServeTLS method serves the application one the given port with TLS encryption.

func (*Cherry) SetErrorHandler

func (c *Cherry) SetErrorHandler(h ErrorHandlerFunc)

SetErrorHandler sets a centralized errorHandler that is invoked whenever a Handler returns an error.

func (*Cherry) SetMethodNotAllowed

func (c *Cherry) SetMethodNotAllowed(h http.Handler)

SetMethodNotAllowed sets a custom handler that is invoked whenever the router could not match the method against the predefined routes.

func (*Cherry) SetNotFound

func (c *Cherry) SetNotFound(h http.Handler)

SetNotFound sets a custom handler that is invoked whenever the router could not match a route against the request url.

func (*Cherry) Static

func (c *Cherry) Static(prefix, dir string)

Static registers the prefix to the router and start to act as a fileserver

app.Static("/public", "./assets").

func (*Cherry) Use

func (c *Cherry) Use(handlers ...Handler)

Use appends a Handler to the middleware. Different middleware can be set for each sub-router.

type Context

type Context struct {
	// Context is a idiomatic way to pass information between requests.
	// More information about context.Context can be found here:
	// https://godoc.org/golang.org/x/net/context
	Context context.Context
	// contains filtered or unexported fields
}

Context is required in each cherry Handler and can be used to pass information between requests.

func (*Context) DecodeJSON

func (c *Context) DecodeJSON(v interface{}) error

DecodeJSON is a helper that decodes the request Body to v. For a more in depth use of decoding and encoding JSON, use the std JSON package.

func (*Context) Form

func (c *Context) Form(name string) string

Form returns the form parameter by its name.

func (*Context) Header

func (c *Context) Header(name string) string

Header returns the request header by name.

func (*Context) JSON

func (c *Context) JSON(code int, v interface{}) error

JSON is a helper function for writing a JSON encoded representation of v to the ResponseWriter.

func (*Context) Param

func (c *Context) Param(name string) string

Param returns the url named parameter given in the route prefix by its name app.Get("/:name", ..) => ctx.Param("name").

func (*Context) Query

func (c *Context) Query(name string) string

Query returns the url query parameter by its name. app.Get("/api?limit=25", ..) => ctx.Query("limit").

func (*Context) Redirect

func (c *Context) Redirect(url string, code int) error

Redirect redirects the request to the provided URL with the given status code.

func (*Context) Request

func (c *Context) Request() *http.Request

Request returns a default http.Request ptr.

func (*Context) Response

func (c *Context) Response() http.ResponseWriter

Response returns a default http.ResponseWriter.

func (*Context) Text

func (c *Context) Text(code int, text string) error

Text is a helper function for writing a text/plain string to the ResponseWriter.

type ErrorHandlerFunc

type ErrorHandlerFunc func(ctx *Context, err error)

ErrorHandlerFunc used for centralize error handling when an error happens in Handler.

type Group

type Group struct {
	Cherry
}

Group act as a sub-router and wil inherit all of its parents middleware.

func (*Group) Reset

func (g *Group) Reset() *Group

Reset clears all middleware.

type Handler

type Handler func(ctx *Context) error

Handler is a cherry idiom for handling http.Requests.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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