Code Monkey home page Code Monkey logo

goexpress's Introduction

GoDoc

goexpress

An Express JS Style HTTP server implementation in Golang. The package make use of similar framework convention as they are in express-js. People switching from NodeJS to Golang often end up in a bad learning curve to start building their webapps, this project is meant to ease things up, its a light weight framework which can be extended to do add any number of functionality.

Hello World

package main
import (
  express "github.com/DronRathore/goexpress"
  request "github.com/DronRathore/goexpress/request"
  response "github.com/DronRathore/goexpress/response"
)

func main (){
  var app = express.Express()
  app.Get("/", func(req *request.Request, res *response.Response, next func()){
    res.Write("Hello World")
    // you can skip closing connection
  })
  app.Start("8080")
}

Router

The router works in the similar way as it does in the express-js. You can have named parameters in the URL or named + regex combo.

func main (){
  var app = express.Express()
  app.Get("/:service/:object([0-9]+)", func(req *request.Request, res *response.Response, next func()){
    res.JSON(req.Params)
  })
  app.Start("8080")
}

Note: You can also adhoc an express.Router() instance too much like it is done in expressjs

package main
import (
  express "github.com/DronRathore/goexpress"
  request "github.com/DronRathore/goexpress/request"
  response "github.com/DronRathore/goexpress/response"
)
var LibRoutes = func (){
  // create a new Router instance which works in similar way as app.Get/Post etc
  var LibRouter = express.Router()
  LibRouter.Get("/lib/:api_version", func(req *request.Request, res *response.Response, next func()){
    res.Json(req.Params["api_version"])
  })
  return *LibRoutes
}() // immediate invocation
func main(){
  var app = express.Express()
  app.Use(LibRoutes) // attaches the Library Routes
  app.Start("8080")
}

Middleware

You can write custom middlewares, wrappers in the similar fashion. Middlewares can be used to add websocket upgradation lib, session handling lib, static assets server handler

func main (){
  var app = express.Express()
  app.Use(func(req *request.Request, res *response.Response, next func()){
    req.Params["I-Am-Adding-Something"] = "something"
    next()
  })
  app.Get("/:service/:object([0-9]+)", func(req *request.Request, res *response.Response, next func()){
    // json will have the key added
    res.JSON(req.Params)
  })
  app.Start("8080")
}

ExpressInterface

You can pass around the instance of express struct across packages using this interface.

func main(){
  var app = express.Express()
  attachHandlers(app)
}
func attachHandlers(instance express.ExpressInterface){
  instance.Use(someMiddleware)
  instance.Set("logging", true)
}

Cookies

import (
  express "github.com/DronRathore/goexpress"
  request "github.com/DronRathore/goexpress/request"
  response "github.com/DronRathore/goexpress/response"
  http "net/http"
  Time "time"
)
func main (){
  var app = express.Express()
  app.Use(func(req *request.Request, res *response.Response, next func()){
    var cookie = &http.Cookie{
      Name: "name",
      Value: "value",
      Expires: Time.Unix(0, 0)
    }
    res.Cookie.Add(cookie)
    req.Params["session_id"] = req.Cookies.Get("session_id")
  })
  app.Get("/", func(req *request.Request, res *response.Response, next func()){
    res.Write("Hello World")
  })
  app.Start("8080")
}

Sending File

You can send a file by using the helper res.SendFile(url string, doNotSendCachedData bool)

func main (){
  var app = express.Express()
  
  app.Get("/public/:filename", func(req *request.Request, res *response.Response, next func()){
	res.SendFile(filename, false)
  })
  app.Start("8080")
}

Note: You can now also send an auto downloadable file too using res.Download api

/*
  @params:
    path: Full path to the file in local machine
    filename: The name to be sent to the client
*/
res.Download(path string, filename string)

Post Body

func main (){
  var app = express.Express()
  app.Use(func(req *request.Request, res *response.Response, next func()){
    res.Params["I-Am-Adding-Something"] = "something"
    next()
  })
  app.Post("/user/new", func(req *request.Request, res *response.Response, next func()){
    type User struct {
			Name string `json:"name"`
			Email string `json:"email"`
		}
		var list = &User{Name: req.Body["name"], Email: req.Body["email"]}
		res.JSON(list)
  })
  app.Start("8080")
}

JSON Post

JSON Post data manipulation in golang is slightly different from JS. You have to pass a filler to the decoder, the decoder assumes the data to be in the same format as the filler, if it is not, it throws an error.

func main (){
  var app = express.Express()
  app.Use(func(req *request.Request, res *response.Response, next func()){
    res.Params["I-Am-Adding-Something"] = "something"
    next()
  })
  app.Post("/user/new", func(req *request.Request, res *response.Response, next func()){
    type User struct {
			Name string `json:"name"`
			Email string `json:"email"`
		}
		var list User
		err := req.JSON.Decode(&list) 
		if err != nil {
			res.Error(400, "Invalid JSON")
		} else {
			res.JSON(list)
		}
  })
  app.Start("8080")
}

File Uploading

Form Data Post

If a request has content-type form-data with a valid bounday param than goexpress will automatically parse and load all the files in request.Files array. It will also populate req.Body if the post/put request contains any text key values.

func(req *request.Request, res *response.Response, next func()){
  if len(req.Files) > 0 {
    // do something
    for _, file := range req.Files {
      name := file.FormName
      type := file.Mime["Content-Type"][0]
      content, err := ioutil.ReadAll(file.File)
      // save content or throw error
    }
  }
}

Normal Post

The request.Request struct has a GetFile() method, which reads a single file at a time, you can make looped calls to retrieve all the files.

func(req *request.Request, res *response.Response, next func()){
	var file *request.File
	while ((file = req.GetFile()) != nil){
		// you can use stream too, ReadAll is for example
		data, err := ioutil.ReadAll(file.Reader)
		// now you can use the data also these keys are available
		// name = file.Name
		// form_input_name = file.FormName
	}
}

Testing

There are no testing added to this package yet, I am hoping to get my hands dirty in testing, if anyone can help me out with this, feel free to open a PR.

Contribution

  • If you want some common must have middlewares support, please open an issue, will add them.
  • Feel free to contribute. :)

goexpress's People

Contributors

chlins avatar dronrathore avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.