Skip to content

Commit

Permalink
Improve routing (gogearbox#64)
Browse files Browse the repository at this point in the history
* improve routing

* update go.sum

* fix allowed method calls

* update readme

* allow cache for post and get methods

* support serving static

* fix prefix lenght value

* improve context comments

* improve comments

* update readme
  • Loading branch information
abahmed authored Jul 26, 2020
1 parent 9362c49 commit fc388d2
Show file tree
Hide file tree
Showing 13 changed files with 1,021 additions and 1,191 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test_and_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:

- name: Build
run: go build

- name: Lint
run: golint -set_exit_status ./...

Expand Down
80 changes: 44 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,13 @@
</p>


**gearbox** :gear: is a web framework for building micro services written in Go with a focus on high performance and memory optimization.
**gearbox** :gear: is a web framework for building micro services written in Go with a focus on high performance and memory optimization. It's built on [fasthttp](https://github.com/valyala/fasthttp) which is **up to 10x faster** than net/http

Currently, **gearbox** :gear: is **under development (not production ready)** and built on [fasthttp](https://github.com/valyala/fasthttp) which is **up to 10x faster** than net/http

In **gearbox**, we care about peformance and memory which will be used by each method while building things up and how we can improve that. It also takes more time to **research** about each component that will be used and **compare** it with different implementations of other open source web frameworks. It may end up writing our **own components** in an optimized way to achieve our goals

### gearbox seeks to be
+ Secure :closed_lock_with_key:
+ Fast :rocket:
+ Simple :eyeglasses:
+ Easy to use
+ Easy to use :eyeglasses:
+ Lightweight


Expand Down Expand Up @@ -58,8 +54,8 @@ func main() {
gb := gearbox.New()

// Define your handlers
gb.Get("/hello", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("Hello World!")
gb.Get("/hello", func(ctx gearbox.Context) {
ctx.SendString("Hello World!")
})

// Start service
Expand All @@ -80,18 +76,8 @@ func main() {
gb := gearbox.New()

// Handler with parameter
gb.Get("/users/:user", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params["user"])
})

// Handler with optional parameter
gb.Get("/search/:pattern?", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params["pattern"])
})

// Handler with regex parameter
gb.Get("/book/:name:([a-z]+[0-3])", func(ctx *gearbox.Context) {
fmt.Printf("%s\n", ctx.Params["name"])
gb.Get("/users/:user", func(ctx gearbox.Context) {
ctx.SendString(ctx.Param("user"))
})

// Start service
Expand All @@ -113,33 +99,32 @@ func main() {
gb := gearbox.New()

// create a logger middleware
logMiddleware := func(ctx *gearbox.Context) {
log.Printf(ctx.RequestCtx.String())
logMiddleware := func(ctx gearbox.Context) {
log.Printf("log message!")
ctx.Next() // Next is what allows the request to continue to the next middleware/handler
}

// create an unauthorized middleware
unAuthorizedMiddleware := func(ctx *gearbox.Context) {
ctx.RequestCtx.SetStatusCode(401) // unauthorized status code
ctx.RequestCtx.Response.SetBodyString("You are unauthorized to access this page!")
unAuthorizedMiddleware := func(ctx gearbox.Context) {
ctx.Status(gearbox.StatusUnauthorized).SendString("You are unauthorized to access this page!")
}

// Register the log middleware for all requests
gb.Use(logMiddleware)

// Define your handlers
gb.Get("/hello", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("Hello World!")
gb.Get("/hello", func(ctx gearbox.Context) {
ctx.SendString("Hello World!")
})

// Register the routes to be used when grouping routes
routes := []*gearbox.Route {
gb.Get("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("User X")
routes := []*gearbox.Route{
gb.Get("/id", func(ctx gearbox.Context) {
ctx.SendString("User X")
}),
gb.Delete("/id", func(ctx gearbox.Context) {
ctx.SendString("Deleted")
}),
gb.Delete("/id", func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("Deleted")
})
}

// Group account routes
Expand All @@ -150,15 +135,38 @@ func main() {

// Define a route with unAuthorizedMiddleware as the middleware
// you can define as many middlewares as you want and have the handler as the last argument
gb.Get("/protected", unAuthorizedMiddleware, func(ctx *gearbox.Context) {
ctx.RequestCtx.Response.SetBodyString("You accessed a protected page")
gb.Get("/protected", unAuthorizedMiddleware, func(ctx gearbox.Context) {
ctx.SendString("You accessed a protected page")
})

// Start service
gb.Start(":3000")
}
```

#### Static Files

```go
package main

import (
"github.com/gogearbox/gearbox"
)

func main() {
// Setup gearbox
gb := gearbox.New()

// Serve files in assets directory for prefix static
// for example /static/gearbox.png, etc.
gb.Static("/static", "./assets")

// Start service
gb.Start(":3000")
}
```


### Contribute & Support
+ Add a [GitHub Star](https://github.com/gogearbox/gearbox/stargazers)
+ [Suggest new features, ideas and optimizations](https://github.com/gogearbox/gearbox/issues)
Expand Down
85 changes: 0 additions & 85 deletions cache.go

This file was deleted.

42 changes: 0 additions & 42 deletions cache_test.go

This file was deleted.

75 changes: 66 additions & 9 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,80 @@ import (
"github.com/valyala/fasthttp"
)

// Context interface
type Context interface {
Next()
Context() *fasthttp.RequestCtx
Param(key string) string
Query(key string) string
SendString(value string) Context
Status(status int) Context
Set(key string, value string)
Get(key string) string
Body() string
}

// handlerFunc defines the handler used by middleware as return value.
type handlerFunc func(ctx *Context)
type handlerFunc func(ctx Context)

// handlersChain defines a handlerFunc array.
type handlersChain []handlerFunc

// Context defines the current context of request and handlers/middlewares to execute
type Context struct {
RequestCtx *fasthttp.RequestCtx
Params map[string]string
handlers handlersChain
index int
type context struct {
requestCtx *fasthttp.RequestCtx
paramValues map[string]string
handlers handlersChain
index int
}

// Next function is used to successfully pass from current middleware to next middleware.
// if the middleware thinks it's okay to pass it.
func (ctx *Context) Next() {
// if the middleware thinks it's okay to pass it
func (ctx *context) Next() {
ctx.index++
ctx.handlers[ctx.index](ctx)
if ctx.index < len(ctx.handlers) {
ctx.handlers[ctx.index](ctx)
}
}

// Param returns value of path parameter specified by key
func (ctx *context) Param(key string) string {
return ctx.paramValues[key]
}

// Context returns Fasthttp context
func (ctx *context) Context() *fasthttp.RequestCtx {
return ctx.requestCtx
}

// SendString sends body of response as a string
func (ctx *context) SendString(value string) Context {
ctx.requestCtx.SetBodyString(value)
return ctx
}

// Status sets the HTTP status code
func (ctx *context) Status(status int) Context {
ctx.requestCtx.Response.SetStatusCode(status)
return ctx
}

// Get returns the HTTP request header specified by field key
func (ctx *context) Get(key string) string {
return GetString(ctx.requestCtx.Request.Header.Peek(key))
}

// Set sets the response's HTTP header field key to the specified key, value
func (ctx *context) Set(key, value string) {
ctx.requestCtx.Response.Header.Set(key, value)
}

// Query returns the query string parameter in the request url
func (ctx *context) Query(key string) string {
return GetString(ctx.requestCtx.QueryArgs().Peek(key))
}

// Body contains the raw body submitted in a POST request
func (ctx *context) Body() string {
return GetString(ctx.requestCtx.Request.Body())
}
6 changes: 2 additions & 4 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// Test passing the request from middleware to handler
func Test_Next(t *testing.T) {
func TestNext(t *testing.T) {
// testing routes
routes := []struct {
path string
Expand All @@ -17,9 +17,7 @@ func Test_Next(t *testing.T) {
}

// get instance of gearbox
gb := new(gearbox)
gb.registeredRoutes = make([]*Route, 0)
gb.settings = &Settings{}
gb := setupGearbox()

// register routes according to method
for _, r := range routes {
Expand Down
Loading

0 comments on commit fc388d2

Please sign in to comment.