Igo: Go Web Framework

Igo is a simple and lightweight microweb-framework for Go, inspired by Bottle.py. It is distributed as a single Go source file and depends only on the Go standard library.


Getting Started


Installation

Igo does not depend on any external libraries. You can just Snip Igo.go into your project directory and start coding:

snip repo github.com/mukailasam/igo --file igo.go

or using go get command

go get github.com/mukailasam/igo

or with Go's module support

simply import igo in your code and Go will automatically fetch it during build:

import "github.com/mukailasam/igo

Basic Example

package main 

import "github.com/mukailasam/igo" 

type Post struct { 
  Title string 
  Body string 
} 
func main() { 
  app := igo.Default()
  app.GET("/hello", func(ctx *igo.Context) { 
    ctx.JSON(200, Post{Title:"Title 1", Body: "Body 1"}) 
  }) 

  app.Run(":1337") 
}

Running the above code:

  1. Copy and save the code above as main.go
  2. Run the code:
  3. go go run main.go 
  4. Open your browser and visit: http://localhost:1337/hello You should see:
  5. { 
    "Title": "Title 1",
    "Body": "Body 1" 
    }

Context & Request Handling


The Context object is passed to every handler and it provides:

Example:

func handler(ctx *igo.Context) { 
  user := ctx.GetParam("user")
  token := ctx.GetHeader("Authorization")
  
  if token == "" { 
    ctx.Abort(401, "Missing token") 
    return 
  } 
  
  ctx.Text(200, "Hello "+user) 
}

Routing


Routes are registered with HTTP methods and path patterns.

app.GET("/users/", handler)
app.POST("/upload", uploadHandler)
app.GET("/assets/*path", staticHandler)

Dynamic Segments

Under the hood, routes are converted to regular expressions and parameter names are extracted.


Response Helpers



Templates



Static Files


Use ServeStatic(urlPrefix, directory):

app.ServeStatic("/static/", "./public")

When a request URL starts with /static/, Igo will attempt to serve the corresponding file under ./public. If file not found or directory, it returns 404 or 403 as appropriate.

Static serving also handles correct MIME types and caching headers (ETag / Last-Modified) when implemented.


Middleware


Middleware functions allow interception before or after handlers:

func Auth(c *igo.Context, next igo.HandlerFunc) {
  if c.GetHeader("X-Token") == "" {
    c.Abort(403, "Forbidden")
    return
  }
  
  next(c)
}

app.Use(Auth)

Built-in middleware:


Error Handling & Recovery


When a handler panics, the Recovery middleware intercepts it, logs, and returns 500 Internal Server Error. You can also call ctx.Error(err) inside any handler; errors get collected and can be logged or handled in middleware (e.g. Logger prints them).


Examples


JSON API
app.GET("/api/users/", func(ctx *igo.Context) {
    user := getUserFromDB(ctx.GetParam("id"))
    ctx.JSON(200, user)
})
Template + Query
app.GET("/search", func(ctx *igo.Context) {
    q := ctx.GetQuery("q")
    results := doSearch(q)
    ctx.HTML(200, "search", results)
})
File Upload
app.POST("/upload", func(ctx *igo.Context) {
    f, fh, err := ctx.FormFile("file")
    if err != nil {
        ctx.Abort(400, "Upload failed")
        return
    }
    defer f.Close()
    saveFile(f, fh.Filename)
    ctx.Text(200, "Upload successful")
})

Roadmap



Community contributions welcome