Ngamux: Simple HTTP Router for Go

ngamux

Simple HTTP router for Go    


Installation

Run this command with correctly configured Go toolchain.

go get github.com/ngamux/ngamux

Examples

package main

import(
  "net/http"
  "github.com/ngamux/ngamux"
)

func main() {
  mux := ngamux.New()
  mux.Get("/", func(rw http.ResponseWriter, r *http.Request) error {
    return ngamux.JSON(rw, ngamux.Map{
      "message": "welcome!",
    })
  })
  
  http.ListenAndServe(":8080", mux)
}

See more examples!

Provided Middlewares

Author: Ngamux
Source Code: https://github.com/ngamux/ngamux 
License: MPL-2.0 license

#go #golang #http 

What is GEEK

Buddha Community

Ngamux: Simple HTTP Router for Go
Fannie  Zemlak

Fannie Zemlak

1599854400

What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features

Ngamux: Simple HTTP Router for Go

ngamux

Simple HTTP router for Go    


Installation

Run this command with correctly configured Go toolchain.

go get github.com/ngamux/ngamux

Examples

package main

import(
  "net/http"
  "github.com/ngamux/ngamux"
)

func main() {
  mux := ngamux.New()
  mux.Get("/", func(rw http.ResponseWriter, r *http.Request) error {
    return ngamux.JSON(rw, ngamux.Map{
      "message": "welcome!",
    })
  })
  
  http.ListenAndServe(":8080", mux)
}

See more examples!

Provided Middlewares

Author: Ngamux
Source Code: https://github.com/ngamux/ngamux 
License: MPL-2.0 license

#go #golang #http 

Nigel  Uys

Nigel Uys

1654358400

Bxog: A Simple and Fast HTTP Router for Go (HTTP Request Multiplexer)

Bxog is a simple and fast HTTP router for Go (HTTP request multiplexer).

Usage

An example of using the multiplexer:

package main

import (
    "io"
    "net/http"

    bx "github.com/claygod/Bxog"
)

// Handlers
func IHandler(w http.ResponseWriter, req *http.Request, r *bx.Router) {
    io.WriteString(w, "Welcome to Bxog!")
}
func THandler(w http.ResponseWriter, req *http.Request, r *bx.Router) {
    params := r.Params(req, "/abc/:par")
    io.WriteString(w, "Params:\n")
    io.WriteString(w, " 'par' -> "+params["par"]+"\n")
}
func PHandler(w http.ResponseWriter, req *http.Request, r *bx.Router) {
    // Getting parameters from URL
    params := r.Params(req, "country")
    io.WriteString(w, "Country:\n")
    io.WriteString(w, " 'name' -> "+params["name"]+"\n")
    io.WriteString(w, " 'capital' -> "+params["city"]+"\n")
    io.WriteString(w, " 'valuta' -> "+params["money"]+"\n")
    // Creating an URL string
    io.WriteString(w, "Creating an URL from the current route (This is an example of creating an another URL):\n")
    io.WriteString(w, r.Create("country", map[string]string{"name": "Russia", "city": "Moscow", "money": "rouble"}))
}

// Main
func main() {
    m := bx.New()
    m.Add("/", IHandler)
    m.Add("/abc/:par", THandler)
    m.Add("/country/:name/capital/:city/valuta/:money", PHandler).
        Id("country"). // For a convinience you can indicate a short ID
        Method("GET")  // It is not necessary to indicate the GET method here as the GET method is used by default but this way is used to set an allowed method
    m.Test()
    m.Start(":9999")
}

Click URLs:

Settings

Necessary changes in the configuration of the multiplexer can be made in the configuration file config.go

Perfomance

Bxog is the fastest router, showing the speed of query processing. Its speed is comparable to the speed of the popular multiplexers: Bone, Httprouter, Gorilla, Zeus. The test is done on a computer with a i3-6320 3.7GHz processor and 8 GB RAM. In short (less time, the better):

  • Bxog 163 ns/op
  • HttpRouter 183 ns/op
  • Zeus 12302 ns/op
  • GorillaMux 14928 ns/op
  • GorillaPat 618 ns/op
  • Bone 47333 ns/op

Detailed benchmark here

API

Methods:

  • New - create a new multiplexer
  • Add - add a rule specifying the handler (the default method - GET, ID - as a string to this rule)
  • Start - start the server indicating the listening port
  • Params - extract parameters from URL
  • Create - generate URL of the available options
  • Shutdown - graceful stop the server
  • Stop - aggressive stop the server
  • Test - Start analogue (for testing only)

Example: m := bxog.New() m.Add("/", IHandler)

Named parameters

Arguments in the rules designated route colon. Example route: /abc/:param , where abc is a static section and :param - the dynamic section(argument).

Static files

The directory path to the file and its nickname as part of URL specified in the configuration file. This constants FILE_PREF and FILE_PATH

Author: Claygod
Source Code: https://github.com/claygod/Bxog 
License: View license

#go #golang #http 

GoLobby Router: A Lightweight Yet Powerful HTTP Router for The Go

 GoLobby Router

GoLobby Router is a lightweight yet powerful HTTP router for the Go programming language. It's built on top of the Go HTTP package and uses radix tree to provide the following features:

  • Routing based on HTTP method and URI
  • Route parameters and parameter patterns
  • Route wildcards
  • Middleware
  • HTTP Responses (such as JSON, XML, Text, Empty, File, and Redirect)
  • Static file serving
  • No footprint!
  • Zero-dependency!

Documentation

Required Go Version

It requires Go v1.11 or newer versions.

Installation

To install this package, run the following command in your project directory.

go get github.com/golobby/router

Quick Start

The following example demonstrates a simple example of using the router package.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    r.GET("/", func(c router.Context) error {
        // c.Request() is original http.Request
        // c.Response() is original http.ResponseWriter
        return c.Text(http.StatusOK, "Hello from GoLobby Router!")
    })
    
    r.PUT("/products/:id", func(c router.Context) error {
        return c.Text(http.StatusOK, "Update product with ID: "+c.Parameter("id"))
    })
    
    log.Fatalln(r.Start(":8000"))
}

HTTP Methods

You can use the Map() method to declare routes. It gets HTTP methods and paths (URIs). There are also some methods available for the most used HTTP methods. These methods are GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. The Any() method defines routes that handles any HTTP method.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func Handler(c router.Context) error {
    return c.Text(http.StatusOK, "Hello from GoLobby Router!")
}

func main() {
    r := router.New()
    
    r.GET("/", Handler)
    r.POST("/", Handler)
    r.PUT("/", Handler)
    r.PATCH("/", Handler)
    r.DELETE("/", Handler)
    r.HEAD("/", Handler)
    r.OPTIONS("/", Handler)
    
    r.Any("/page", Handler)
    
    r.Map("GET", "/", Handler)
    r.Map("CUSTOM", "/", Handler)
        
    log.Fatalln(r.Start(":8000"))
}

Route Parameters

To specify route parameters, prepend a colon like :id. In default, parameters could be anything but you can determine a regex pattern using the Define() method. Of course, regex patterns slow down your application, and it is recommended not to use them if possible. To catch and check route parameters in your handlers, you'll have the Parameters(), Parameter(), and HasParameter() methods.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // "id" parameters must be numeric
    r.Define("id", "[0-9]+")
   
    // a route with one parameter
    r.GET("/posts/:id", func(c router.Context) error {
        return c.Text(http.StatusOK, c.Parameter("id"))
    })
    
    // a route with multiple parameters
    r.GET("/posts/:id/comments/:cid", func(c router.Context) error {
        return c.JSON(http.StatusOK, c.Parameters())
    })
    
    log.Fatalln(r.Start(":8000"))
}

Wildcard Routes

Wildcard routes match any URI with the specified prefix. The following example shows how it works.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Other routes with the same pattern should come first.
    r.GET("/pages/contact", ContactHandler)
    
    r.GET("/pages/*", PagesHandler)
    // It matches:
    // - /pages/
    // - /pages/about
    // - /pages/about/us
    // - /pages/help
    
    log.Fatalln(r.Start(":8000"))
}

Serving Static Files

The Files method is provided to serve static files directly. The example below demonstrate how to use it.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Other routes with the same pattern should come first.
    r.GET("/api", YourApiHandler)
    
    // The path (URI) must end with `*`.
    r.Files("/*", "./files")
    // example.com/            ==> ./files/index.html
    // example.com/photo.jpg   ==> ./files/photo.jpg
    // example.com/notes/1.txt ==> ./files/notes/1.txt
    
    log.Fatalln(r.Start(":8000"))
}

Named Routes

Named routes allow the convenient generation of URLs or redirects for specific routes. You may specify a name for a route by chaining the SetName() method onto the route definition:

package main

import (
    "github.com/golobby/router"
    "github.com/golobby/router/pkg/response"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    r.GET("/", func(c router.Context) error {
        return c.Text(http.StatusOK, "I am the home!")
    }).SetName("home")
    
    r.GET("/posts/:id", func(c router.Context) error {
        return c.Text(http.StatusOK, "I am a post!")
    }).SetName("post")
    
    r.GET("/links", func(c router.Context) error {
        return c.JSON(http.StatusOK, response.M{
            "home": c.URL("home", nil), // "/"
            "post-1": c.URL("post", map[string]string{"id": "1"}), // "/posts/1"
            "post-2": c.URL("post", map[string]string{"id": "2"}), // "/posts/2"
        })
    })
    
    log.Fatalln(r.Start(":8000"))
}

Responses

The router comes with Empty, Redirect, Text, HTML, JSON, PrettyJSON, XML, PrettyXML, and Bytes responses out of the box. The examples below demonstrate how to use built-in and custom responses.

package main

import (
    "github.com/golobby/router"
    "github.com/golobby/router/pkg/response"
    "log"
    "net/http"
)

func main() {
    r := router.New()

    r.GET("/empty", func(c router.Context) error {
        return c.Empty(204)
    })

    r.GET("/redirect", func(c router.Context) error {
        return c.Redirect(301, "https://github.com/golobby/router")
    })

    r.GET("/text", func(c router.Context) error {
        return c.Text(200, "A text response")
    })

    r.GET("/html", func(c router.Context) error {
        return c.HTML(200, "<p>A HTML response</p>")
    })

    r.GET("/json", func(c router.Context) error {
        return c.JSON(200, User{"id": 13})
    })

    r.GET("/json", func(c router.Context) error {
        return c.JSON(200, response.M{"message": "Using response.M helper"})
    })

    r.GET("/json-pretty", func(c router.Context) error {
        return c.PrettyJSON(200, response.M{"message": "A pretty JSON response!"})
    })

    r.GET("/xml", func(c router.Context) error {
        return c.XML(200, User{"id": 13})
    })

    r.GET("/xml-pretty", func(c router.Context) error {
        return c.PrettyXML(200, User{"id": 13})
    })

    r.GET("/bytes", func(c router.Context) error {
        return c.Bytes(200, []bytes("Some bytes!"))
    })

    r.GET("/file", func(c router.Context) error {
    return c.File(200, "text/plain", "text.txt")
    })

    r.GET("/custom", func(c router.Context) error {
        c.Response().Header().Set("Content-Type", "text/csv")
        return c.Bytes(200, []bytes("Column 1, Column 2, Column 3"))
    })

    log.Fatalln(r.Start(":8000"))
}

Groups

You may put routes with similar attributes in groups. Currently, prefix and middleware attributes are supported.

Group by prefix

The example below demonstrates how to group routes with the same prefix.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    r.WithPrefix("/blog", func() {
        r.GET("/posts", PostsHandler)    // "/blog/posts"
        r.GET("/posts/:id", PostHandler) // "/blog/posts/:id"
        r.WithPrefix("/pages", func() {
            r.GET("/about", AboutHandler)     // "/blog/pages/about"
            r.GET("/contact", ContactHandler) // "/blog/pages/contact"
        })
    })
    
    log.Fatalln(r.Start(":8000"))
}

Group by middleware

The example below demonstrates how to group routes with the same middleware.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func AdminMiddleware(next router.Handler) router.Handler {
    return func(c router.Context) error {
        // Check user roles...
        return next(c)
    }
}

func main() {
    r := router.New()
    
    r.WithMiddleware(AdminMiddleware, func() {
        r.GET("/admin/users", UsersHandler)
        r.GET("/admin/products", ProductsHandler)
    })
    
    log.Fatalln(r.Start(":8000"))
}

Group by middlewares

The example below demonstrates how to group routes with the same middlewares.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    middlewares := []router.Middleware{Middleware1, Middleware2, Middleware3}
    r.WithMiddlewares(middlewares, func() {
        r.GET("/posts", PostsIndexHandler)
    })
    
    log.Fatalln(r.Start(":8000"))
}

Group by multiple attributes

The group() method helps you create a group of routes with the same prefix and middlewares.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    r.Group("/blog", []router.Middleware{Middleware1, Middleware2}, func() {
        r.GET("/posts", PostsHandler)
        r.GET("/posts/:id/comments", CommentsHandler)
    })
    
    log.Fatalln(r.Start(":8000"))
}

Basic Attributes

Your application might need a base prefix or global middlewares. In this case, you can set up these base attributes before defining routes.

Base prefix

The following example shows how to set a base prefix for all routes.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Add a prefix to all routes
    r.AddPrefix("/blog")

    r.GET("/posts", PostsHandler)
    r.GET("/posts/:id/comments", CommentsHandler)
    
    log.Fatalln(r.Start(":8000"))
}

Base middlewares

The following example shows how to set a base middlewares for all routes.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Add a single middleware
    r.AddMiddleware(LoggerMiddleware)
    
    // Add multiple middlewares at once
    r.AddMiddlewares([]router.Middleware{AuthMiddleware, ThrottleMiddleware})

    r.GET("/users", UsersHandler)
    r.GET("/users/:id/files", FilesHandler)
    
    log.Fatalln(r.Start(":8000"))
}

404 Handler

In default, the router returns the following HTTP 404 response when a requested URI doesn't match any route.

{"message": "Not found."}

You can set your custom handler like the following example.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Custom (HTML) Not Found Handler
    r.SetNotFoundHandler(func(c router.Context) error {
        return c.HTML(404, "<p>404 Not Found</p>")
    })

    r.GET("/", Handler)
    
    log.Fatalln(r.Start(":8000"))
}

Error Handling

Your handlers might return an error while processing the HTTP request. This error can be produced by your application logic or failure in the HTTP response. By default, the router logs it using Golang's built-in logger into the standard output and returns the HTTP 500 response below.

{"message": "Internal error."}

It's a good practice to add a global middleware to catch all these errors, log and handle them the way you need. The example below demonstrates how to add middleware for handling errors.

package main

import (
    "github.com/golobby/router"
    "log"
    "net/http"
)

func main() {
    r := router.New()
    
    // Error Handler
    r.AddMiddleware(func (next router.Handler) router.Handler {
        return func(c router.Context) error {
            if err := next(c); err != nil {
                myLogger.log(err)
                return c.HTML(500, "<p>Something went wrong</p>")
            }
            
            // No error will raise to the router base handler
            return nil
        }
    })

    r.GET("/", Handler)
    
    log.Fatalln(r.Start(":8000"))
}

Author: Golobby
Source Code: https://github.com/golobby/router 
License: MIT license

#go #golang #http 

Jamie  Graham

Jamie Graham

1642219020

Graphql-go: Simple Low-level GraphQL HTTP Client for Go

graphql

Low-level GraphQL client for Go.

  • Simple, familiar API
  • Respects context.Context timeouts and cancellation
  • Build and execute any kind of GraphQL request
  • Use strong Go types for response data
  • Use variables and upload files
  • Simple error handling

Installation

Make sure you have a working Go environment. To install graphql, simply run:

$ go get github.com/machinebox/graphql

Usage

import "context"

// create a client (safe to share across requests)
client := graphql.NewClient("https://machinebox.io/graphql")

// make a request
req := graphql.NewRequest(`
    query ($key: String!) {
        items (id:$key) {
            field1
            field2
            field3
        }
    }
`)

// set any variables
req.Var("key", "value")

// set header fields
req.Header.Set("Cache-Control", "no-cache")

// define a Context for the request
ctx := context.Background()

// run it and capture the response
var respData ResponseStruct
if err := client.Run(ctx, req, &respData); err != nil {
    log.Fatal(err)
}

File support via multipart form data

By default, the package will send a JSON body. To enable the sending of files, you can opt to use multipart form data instead using the UseMultipartForm option when you create your Client:

client := graphql.NewClient("https://machinebox.io/graphql", graphql.UseMultipartForm())

For more information, read the godoc package documentation or the blog post.

Download Details:
Author: machinebox
Source Code: https://github.com/machinebox/graphql
License: Apache-2.0 License

#graphql #go #http #golang