Juliet

轻量级 Golang 中间件
授权协议 MIT
开发语言 Google Go
所属分类 应用工具、 个人助理软件
软件类型 开源软件
地区 不详
投 递 者 毛胜
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Juliet 是一款轻量级的 Golang 中间件链接助手,将 Context(地图)对象从中间件传递到下一个。

示例:

package main

import (
    "net/http"
    "log"
    "net"
    "fmt"

    "github.com/root-gg/juliet"
)

// Juliet is a lightweight middleware chaining helper that pass a Context (map) object
// from a middleware to the next one.
//
// Middlewre is a pattern where http request/response are passed through many handlers to reuse code.

// For example this classic middleware log the requested url
func logMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Our middleware logic goes here...
        log.Println(r.URL.String())

        // Pass the request to the next middleware / handler
        next.ServeHTTP(w, r)
    })
}

// Juliet adds a context parameter to the middleware pattern that will be passed along the Chain.
// For example this middleware puts the request's source IP address in the context.
func getSourceIpMiddleware(ctx *juliet.Context, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        // Get the source IP from the request remote address
        ip, _, err := net.SplitHostPort(r.RemoteAddr)

        // You can handle failure at any point of the chain by not calling next.ServeHTTP
        if err != nil {
            http.Error(w, "Unable to parse source ip address", 500)
            return
        }

        // Save the source ip in the context
        ctx.Set("ip", ip)

        // Pass the request to the next middleware / handler
        next.ServeHTTP(w, r)
    })
}

// As a context is nothing more that a map[interface{}]interface{} with syntactic sugar you have to ensure you
// check types of values you get from the context. To keep your code clean you can write helpers to do that and keep
// type safety everywhere.
func getSourceIp(ctx *juliet.Context) string {
    if sourceIP, ok := ctx.Get("ip"); ok {
        return sourceIP.(string)
    }
    return ""
}

// The last link of a middleware chain is the application Handler
func pingHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("pong\n"))
}

// Juliet can also pass the context parameter to application Handlers
func ipHandler(ctx *juliet.Context, resp http.ResponseWriter, req *http.Request) {
    // write http response
    resp.Write([]byte(fmt.Sprintf("your IP address is : %s\n", getSourceIp(ctx))))
}

func main(){
    // Juliet links middleware and handler with chain objects
    chain := juliet.NewChain()

    // Chain objects are immutable and any operation on it returns a new chain object.
    // You can append one or more middleware to the chain at a time using the Append method.
    chain = chain.Append(getSourceIpMiddleware)

    // You can append a middleware to the beginning of the chain with the AppendChain method.
    // When working with a non context-aware ( Juliet ) middleware you have to use the Adapt method.
    chain = juliet.NewChain(juliet.Adapt(logMiddleware)).AppendChain(chain)

    // Now we have this middleware chain : logUrl > getSourceIp > ApplicationHandler
    // We could have built it in one pass this way :
    //  chain := juliet.NewChain(juliet.Adapt(logMiddleware),getSourceIpMiddleware)

    // It's now time to add some application handlers and to bind everything to some HTTP route.

    // With a context handler
    http.Handle("/ip", chain.Then(ipHandler))

    // With a classic http.HandlerFunc
    http.Handle("/ping", chain.ThenHandlerFunc(pingHandler))

    // With a classic http.Handler
    http.Handle("/404", chain.ThenHandler(http.NotFoundHandler()))

    log.Fatal(http.ListenAndServe(":1234", nil))
}

// $ go run main.go
// 2016/02/01 12:20:39 /ip
// 2016/02/01 12:20:44 /ping
// 2016/02/01 12:20:56 /404
//
// $ curl 127.0.0.1:1234/ip
// your IP address is : 127.0.0.1
// $ curl 127.0.0.1:1234/ping
// pong
// $ curl 127.0.0.1:1234/404
// 404 page not found
 相关资料
  • 问题内容: JPanel和JFrame有什么区别,以及与轻量级,重量级的关系? 问题答案: JPanel是允许将多个UI组件放在一起的容器。JFrame是使用Swing编写的窗口。 所有的Swing组件都是所谓的“轻型”组件,因为它们是用Java编写的。例如,如果您运行Swing应用程序并尝试使用UI分析工具(例如Windows中的WinSpy)对其进行分析,则只会看到一个元素:窗口(JFrame

  • 主要内容:使用普通函数创建 goroutine,使用匿名函数创建goroutine在编写 Socket 网络程序时,需要提前准备一个线程池为每一个 Socket 的收发包分配一个线程。开发人员需要在线程数量和 CPU 数量间建立一个对应关系,以保证每个任务能及时地被分配到 CPU 上进行处理,同时避免多个任务频繁地在线程间切换执行而损失效率。 虽然,线程池为逻辑编写者提供了线程分配的抽象机制。但是,如果面对随时随地可能发生的并发和线程处理需求,线程池就不是非常直观和方便了。能否

  • Jenkins Pipeline插件有一个称为“轻量级签出”的功能,其中主服务器仅从repo中提取Jenkinsfile,而不是整个repo。配置屏幕中有一个相应的复选框。我想在多分支管道中进行轻量级签出,但我在多分支配置屏幕中没有看到复选框。有什么想法如何实现这一点吗?我注意到一些关闭的问题表明此功能可用,但我无法找到任何有关如何实现它的细节。 相关资料: https://issues.jenk

  • 问题内容: 题 我正在寻找Java内存对象缓存API。有什么建议吗?您过去使用过什么解决方案? 当前 现在,我只是在使用地图: 要求 我需要扩展缓存以包括以下基本功能: 最大尺寸 生存时间 但是,我不需要更复杂的功能,例如: 来自多个进程的访问(缓存服务器) 持久性(到磁盘) 意见建议 内存中缓存: Guava CacheBuilder-活动开发。请参阅此演示文稿。 LRUMap-通过API配置。

  • 问题内容: 我目前在一个网站上工作,该网站必须存在于内存可用性非常低的VM上(目前被告知要达到512mb)。不幸的是,至少在不久的将来,数据库和Web应用程序必须是同一台服务器。 现在,我已经在这里通读了一些问题,并尝试进行自己的研究,但是这里有很多选择。从本质上讲,什么是可以安装的轻巧的数据库服务器?SQL或NoSQL并不重要;它不会占用大量数据库资源,但我现在不想随我现在选择的内容而受到限制。

  • 问题内容: 是否有一个提供发布/订阅模式的Java轻量级框架? 一些理想的功能 支持泛型 向发布者注册多个订阅者 API主要是接口和一些有用的实现 完全不需要内存,持久性和事务保证。 我了解JMS,但这对我来说太过分了。发布/订阅的数据是文件系统扫描的结果,扫描结果被馈送到另一个组件进行处理,然后在将其馈给另一个组件之前进行处理,依此类推。 编辑:所有在同一过程中。bean的PropertyCha