Skip to content
/ lilypad Public

A lightweight web application framework in Go

License

Notifications You must be signed in to change notification settings

ynori7/lilypad

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lilypad go.dev reference Build Status Coverage Status Go Report Card

A lightweight web application framework in Go.

Features

Here is a brief overview of the feature set provided by the Lilypad framework. A detailed example can be found in examples.

Routing

The Lilypad framework provides a simple wrapper around the Gorilla mux router. This allows you to use Lilypad's handlers to simplfy response writing and error handling.

The framework keeps a global router which allows you to register routes close to the handlers which control them without having to pass a router around everywhere.

To add a route, simply register it like this:

import "github.com/ynori7/lilypad/http"

...

http.RegisterRoutes(http.Route{
    Path:    "/hello/{name}",
    Handler: Hello,
})

RegisterRoutes is variardic, so it's possible to register multiple routes at once:

http.RegisterRoutes([]http.Route{
    {
        Path:    "/hello/{name}",
        Handler: Hello,
    },
    {
        Path:    "/goodbye/{name}",
        Handler: Goodbye,
    },
}...)

Handlers

Lilypad's handler definition makes it easier to build your http handlers. You no longer need to care about writing responses for ever place where the method exists. You simply return either a SuccessResponse or an ErrorResponse.

For example:

import (
	"github.com/ynori7/lilypad/http"
)

func Hello(r http.Request) http.Response {
    name := http.GetVar(r, "name")

    if !isValidName(name) {
        return http.ErrorResponse(errors.BadRequestError("Names should be non-empty and contain only letters"))
    }

    ...

    return SuccessResponse(resp)

It's also possible to return a RedirectResponse to redirect to another page.

You can also specify the cache duration like this:

return SuccessResponse(resp).WithMaxAge(300)

Or any other arbitrary headers using the WithHeaders() method.

Errors

The errors package provides a definition for HttpErros as well as convenient wrappers for getting some of the most common error types.

One key attribute of the errors package is the HttpError's Write() method. This method will present the error in a useful format depending on the configuration. In your main.go, you can set errors to be presented in a JSON format, HTML format, or plaintext format.

errors.UseMarkupErrors(errorHtmlTemplate)
//or
errors.UseJsonErrors()
//or
errors.UsePlaintextErrors() //the default

Logging

The log package wraps the Sirupsen Logrus library and adds a few useful additions such as the WithRequest method which returns a logger with some fields populated from the HTTP request such as the client's IP address.

Templating

The view package provides a minimalistic method to RenderTemplate which accepts a template body as a string and the data used to render it.

Alternatively, you can use nested templates by registering your base layouts like this:

view.SetLayoutDirectory("path/to/layouts")

This will configure the framework to load all files with the gohtml extension. Next you can render a view like this:

out, err := view.New("layoutName", "templates/specificTemplate.gohtml").Render(myData)

Here is an example layout.gohtml:

{{ define "layoutName" }}
<html>
<body>
{{ template "body" . }}
</body>
</html>

And an example specificTemplate.gohtml:

{{ define "body" }}
<h1>My Page!</h1>
<article>blahblah</article>
{{ end }}

It also has a global register of template functions which can be easily registered like this:

view.RegisterGlobalTemplateFuncs(template.FuncMap{
    "UppercaseFirstLetter": func(s string) string {
        return strings.Title(strings.ToLower(s))
    },
})

And from any template, the function can be used like this:

{{ UppercaseFirstLetter .Str }}