Skip to content

A thin layer over the standard http library to help improve routing, context, and middleware chaining

Notifications You must be signed in to change notification settings

Phillip-England/go-quickstart

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-quickstart

go-quickstart is a small layer over the standard http library in Go to make building routes and chaining middleware as simple as possible

Requirements

Go version 1.22.0 or greater required

Tailwind

This repo comes with a script to run tailwind at /tailwind.sh but you'll need to install the tailwind binary and place it somewhere on your system's PATH.

Make sure the binary is named, tailwindcss.

Installation

Clone the repo:

git clone https://github.com/phillip-england/go-quickstart <your-app-name>

Serving

From the root of your app run:

go run main.go

The application server on localhost:8080 by default. This can be easliy changed in main.go.

Features

Here is an overview of the provided features.

Router

A router can be created:

r, err := route.NewRouter()
if err != nil {
    panic(err)
}

Routes can be added:

r.Add("GET /", handler.HandleHome)

Then serve your app:

port := "8080"
r.Serve(port, fmt.Sprintf("Server is running on port %s", port))

Handlers

Here is a simple Handler:

func HandleHome(httpContext *httpcontext.Context, w http.ResponseWriter, r *http.Request) {
	err := httpContext.Templates.ExecuteTemplate(w, "base.html", templates.BasePageData{
		Title:   "Home",
		Content: templates.ExecuteTemplate(httpContext.Templates, "hello-world.html", nil),
	})
	if err != nil {
		fmt.Println(err)
		http.Error(w, "Internal Server Error", http.StatusInternalServerError)
		return
	}
}

It simply executes a few templates found in /html and checks for any errors.

Handlers are functions with the following definition:

type HandlerFunc func(ctx *httpcontext.Context, w http.ResponseWriter, r *http.Request)

Notice how the HandlerFunc takes in a *httpcontext.Context? This just enables you to share data between your middleware and handler.

To add more values to your context, simply update ./internal/httpcontext/httpcontext.go:

type Context struct {
	context.Context
	Templates *template.Template
	StartTime time.Time
    NewContextValue string // new value added
}

Now the NewContextValue can be set and shared amoung your middleware and handler.

Middleware

Middleware can be "chained" onto handlers:

func CustomMiddleware(ctx *httpcontext.Context, w http.ResponseWriter, r *http.Request) error {
	fmt.Println("Executing custom middleware")
	return nil
}

r.Add("GET /", handler.HandleHome, CustomMiddleware) // chaining middleware

You can even chain the same middleware multiple times:

r.Add("GET /", handler.HandleHome, CustomMiddleware, CustomMiddleware)

The definition for MiddlewareFunc is exactly like HandlerFunc except MiddlewareFunc can return an error:

type MiddlewareFunc func(ctx *httpcontext.Context, w http.ResponseWriter, r *http.Request) error

If a MiddlewareFunc returns an error, the request/response cycle will exit:

func ExitMiddleware(ctx *httpcontext.Context, w http.ResponseWriter, r *http.Request) error {
	w.Write([]byte("exiting from middleware\n"))
	return errors.New("exit!")
}
r.Add("GET /exit", handler.HandleHome, CustomMiddleware, ExitMiddleware)

About

A thin layer over the standard http library to help improve routing, context, and middleware chaining

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published