About today

Chapi Go Toy Web Framework

· by Otto Giron · Read in about 3 min · (634 Words)
golang

On my quest of learning I heard about this relatively new language called go. I don’t remember well the details of why I had the desire of learning it, but as I normally do in order to learn a new language or tool, I write code to test the features and get an overview of what I can accomplish using it and… I also read the first chapters of this book: Programing in go

My first thought was to write a simple REST API but since I’ve been working with Node hapijs lately I wondered if I could write a super simple framework inspired in the hapijs plugin system which I really like.

Chapi

So Chapi is a Toy Web Framework inspired in hapijs (Almost chappie), so it basically implements a simple plugin system, routes using the gorilla mux, and a server using negroni.

Chapi Server

github.com/ottogiron/chapi/server.Sever

Chapi server allows you to easily create an http server, define routes, and register plugins.

Creating a simple server:

connectionString := ":8080"
s := server.NewServer()
err := s.Run(connectionString)
if err != nil {
  fmt.Println("Error when running server", err)
}

Chapi Plugin

github.com/ottogiron/chapi/server.BasePlugin

Chapi implements a plugin systems which allows you to break your logic in multiple reusable pieces.

Plugin Definition

This is how you define a plugin:

type MyPlugin struct {
    *server.BasePlugin
}

//Here you'll recieve a server reference
func (p *MyPlugin) Register(s server.Server) {

}

//Unique plugin name (Optional)
func (p *MyPlugin) Name() string {
    return "MyPlugin"
}

//Array of plugins that should run before this one(Optional)
func (p *MyPlugin) Dependencies() []string {
    return []string{"SomeDependencyPluginName"}
}

Registering a plugin

Assuming you’ve already initialized a server «s»

s.Register(&MyPlugin{})

Chapi Routes

You can register route handlers using Chapi Server. It uses the same route syntax of gorilla mux

s.HandleFunc("/", handleHello).Methods("GET")

Example

Prerequisites

  • go => 1.5

Creating a simple server

Get Chapi:

go get github.com/ottogiron/chapi

Create a new directory:

mkdir $GOPATH/src/chapi-example
cd chapi-example

Create a new file called main.go and paste this:

package main

import (
	"fmt"

	"github.com/ottogiron/chapi/server"
)

func main() {

	connectionString := ":8080"
	s := server.NewServer()
	err := s.Run(connectionString)
	if err != nil {
		fmt.Println("Error when running server", err)
	}

}

Run the server:

go run main.go

Go to http://localhost:8080. You should see something like this:

404 page not found

So don’t worry everything is fine. The server is running on port 8080 but we still need to define a route to handle the root «/» path.

Creating a controller plugin to handle the root path.

Add this after the import statement

type HelloController struct {
	*server.BasePlugin
}

func (c *HelloController) Register(s server.Server) {
	s.HandleFunc("/", handleHello).Methods("GET")
}

func handleHello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "!!!Hello Chapi")
}

Register HelloController Plugin:

func main() {

	connectionString := ":8000"
	s := server.NewServer()
	s.Register(&HelloController{})
	err := s.Run(connectionString)
	if err != nil {
		fmt.Println("Error when running server", err)
	}

}

Your final main.go should look something like this:

package main

import (
	"fmt"
	"net/http"

	"github.com/ottogiron/chapi/server"
)

type HelloController struct {
	*server.BasePlugin
}

func (c *HelloController) Register(s server.Server) {
	s.HandleFunc("/", handleHello).Methods("GET")
}

func handleHello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "!!!Hello Chapi")
}

func main() {

	connectionString := ":8000"
	s := server.NewServer()
	s.Register(&HelloController{})
	err := s.Run(connectionString)
	if err != nil {
		fmt.Println("Error when running server", err)
	}

}

Restart the server:

press ctrl + c

… and run it again:

go run main.go

Go to http://localhost:8080, you’ll see something like this:

!!!Hello Chapi

A Toy Web Framework ?

This is my first piece of go code, it doesn’t have unit testing and it isn’t the best example of go code style. At this point I have written some others tools using the language and I’m still learning. Hopefully I’ll find the time to get back to this project and improve it at some point.

The code for this example is available on github: https://github.com/ottogiron/chapi-example

Comments