hime

package module
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Dec 25, 2017 License: MIT Imports: 24 Imported by: 6

README

Hime

Go Report Card GoDoc

Hime is a Go Web Framework.

Why Framework

I like net/http but... there are many duplicated code when working on multiple projects, plus no standard. Framework creates a standard for developers.

Why Another Framework

There're many Go framework out there. But I want a framework that works with any net/http compatible libraries seamlessly.

For example, you can choose any router, any middlewares, or handlers that work with standard library.

Other framework don't allow this. They have built-in router, framework-specific middlewares.

Core focus

  • Add standard to code
  • Compatible with any net/http compatible router
  • Compatible with http.Handler without code change
  • Compatible with net/http middlewares without code change
  • Use standard html/template for view
  • Built-in core functions for build web server
  • Reduce developer bug

What is this framework DO NOT focus

  • Speed
  • One framework do everything

Example

func main() {
	hime.New().
		Template("index", "index.tmpl", "_layout.tmpl").
		Minify().
		Routes(hime.Routes{
			"index": "/",
		}).
		BeforeRender(addHeaderRender).
		Handler(routerFactory).
		GracefulShutdown().
		ListenAndServe(":8080")
}

func routerFactory(app hime.App) http.Handler {
	mux := http.NewServeMux()
	mux.Handle(app.Route("index"), hime.Wrap(indexHandler))
	return middleware.Chain(
		logRequestMethod,
		logRequestURI,
	)(mux)
}

func logRequestURI(h http.Handler) http.Handler {
	return hime.Wrap(func(ctx hime.Context) hime.Result {
		log.Println(ctx.Request().RequestURI)
		return ctx.Handle(h)
	})
}

func logRequestMethod(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Println(r.Method)
		h.ServeHTTP(w, r)
	})
}

func addHeaderRender(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
		h.ServeHTTP(w, r)
	})
}

func indexHandler(ctx hime.Context) hime.Result {
	if ctx.Request().URL.Path != "/" {
		return ctx.RedirectTo("index")
	}
	return ctx.View("index", map[string]interface{}{
		"Name": "Acoshift",
	})
}

Compatibility with net/http

Handler

Hime doesn't have built-in router, you can use any http.Handler.

hime.Wrap wraps hime.Handler into http.Handler, so you can use hime's handler anywhere in your router that support http.Handler.

Middleware

Hime use native func(http.Handler) http.Handler for middleware. You can use any middleware that compatible with this type.

func logRequestMethod(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Println(r.Method)
		h.ServeHTTP(w, r)
	})
}

You can also use hime's handler with middleware

func logRequestURI(h http.Handler) http.Handler {
	return hime.Wrap(func(ctx hime.Context) hime.Result {
		log.Println(ctx.Request().RequestURI)
		return ctx.Handle(h)
	})
}

Why return Result

Bacause many developers forgot to return to end handler

func signInHandler(w http.ResponseWriter, r *http.Request) {
	username := r.FormValue("username")
	if username == "" {
		http.Error(w, "username required", http.StatusBadRequest)
		return // many return like this, sometime developers forgot about it
	}
	...
}

with Result

func signInHandler(ctx hime.Context) hime.Result {
	username := r.FormValue("username")
	if username == "" {
		return ctx.Status(http.StatusBadRequest).Error("username required")
	}
	...
}

Why not return error, like this...

func signInHandler(ctx hime.Context) error {
	username := r.FormValue("username")
	if username == "" {
		return ctx.Status(http.StatusBadRequest).Error("username required")
	}
	...
}

Then, what if you return an error ?

return err

Hime won't handle error for you :D

You can see that hime won't response anything, you must handle on your own.

Why some functions use panic

Hime try to reduce developer errors, some error can detect while development. Hime will panic for that type of errors.

Useful handlers and middlewares

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Wrap

func Wrap(h Handler) http.Handler

Wrap wraps hime handler with http.Handler

Types

type App

type App interface {
	http.Handler

	// TemplateDir sets directory to load template,
	// default is "view"
	TemplateDir(path string) App

	// TemplateRoot sets root layout using t.Lookup,
	// default is "layout"
	TemplateRoot(name string) App

	// TemplateFuncs adds template funcs while load template
	TemplateFuncs(funcs ...template.FuncMap) App

	// Component adds given templates to every templates
	Component(filename ...string) App

	// Template loads template into memory
	Template(name string, filename ...string) App

	// BeforeRender runs given middleware for before render,
	// ex. View, JSON, String, Bytes, CopyForm, etc.
	BeforeRender(m middleware.Middleware) App

	// Minify enables minify when render html, css, js
	Minify() App

	// Handler sets the handler factory
	Handler(factory HandlerFactory) App

	// Routes registers route name and path
	Routes(routes Routes) App

	// GracefulShutdown runs server as graceful shutdown,
	// can works only when start server with app.ListenAndServe
	GracefulShutdown() App

	// ShutdownTimeout sets graceful shutdown timeout
	ShutdownTimeout(d time.Duration) App

	// ListenAndServe starts web server
	ListenAndServe(addr string) error

	// Route gets route path from given name
	Route(name string) string
}

App is the hime app

func New

func New() App

New creates new app

type Context

type Context interface {
	context.Context

	// Request returns http.Request from context
	Request() *http.Request

	// ResponseWrite returns http.ResponseWriter from context
	ResponseWriter() http.ResponseWriter

	// Status sets response status
	Status(code int) Context

	// Request functions
	ParseForm() error
	ParseMultipartForm(maxMemory int64) error
	Form() url.Values
	PostForm() url.Values
	FormValue(key string) string
	PostFormValue(key string) string
	FormFile(key string) (multipart.File, *multipart.FileHeader, error)
	MultipartForm() *multipart.Form
	MultipartReader() (*multipart.Reader, error)
	Method() string

	// Redirect redirects to given url
	Redirect(url string, params ...interface{}) Result

	// SafeRedirect extracts only path from url then redirect
	SafeRedirect(url string, params ...interface{}) Result

	// RedirectTo redirects to named route
	RedirectTo(name string, params ...interface{}) Result

	// Error wraps http.Error
	Error(error string) Result

	// NotFound wraps http.NotFound
	NotFound() Result

	// NoContent renders empty body with http.StatusNoContent
	NoContent() Result

	// View renders template
	View(name string, data interface{}) Result

	// JSON renders json
	JSON(data interface{}) Result

	// String renders string with format
	String(format string, a ...interface{}) Result

	// StatusText renders String when http.StatusText
	StatusText() Result

	// CopyFrom copies source into response writer
	CopyFrom(src io.Reader) Result

	// Bytes renders bytes
	Bytes(b []byte) Result

	// File renders file
	File(name string) Result

	// Handle wrap h with Result
	Handle(h http.Handler) Result
}

Context is the hime context

type Handler

type Handler func(Context) Result

Handler is the hime handler

type HandlerFactory

type HandlerFactory func(App) http.Handler

HandlerFactory is the function for create router

type Result

type Result interface {
	Response(w http.ResponseWriter, r *http.Request)
}

Result is the handler result

type ResultFunc

type ResultFunc func(w http.ResponseWriter, r *http.Request)

ResultFunc is the result function

func (ResultFunc) Response

func (f ResultFunc) Response(w http.ResponseWriter, r *http.Request)

Response implements Result interface

type Routes added in v0.0.4

type Routes map[string]string

Routes is the map for route name => path

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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