nats_proxy

package module
v0.0.0-...-e7b17b8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2017 License: Apache-2.0 Imports: 16 Imported by: 0

README

GoReport GoDoc

nats-proxy

http on the front; nats on the backend

nats-proxy is a library for building http micro services on NATS and consists of

  1. an HTTP to NATS gateway that proxies HTTP requests and routes them over NATS
  2. a router that wraps an existing http.Handler to service the calls.

The aim of nats-proxy is to take the pain out of service discovery while at the same time preserving the existing tooling around http.Handler

Why NATS

In a typical micro service environment, service discovery or how one micro service finds another micro service can be a complicated thing. Various tools have been developed to manage the service discovery issue including consul, etcd, and eureka.

Leverage NATS for service discovery, we dramatically reduce the amount of effort required for services to discover each other.

Status

Library is very fresh, but is already used in production so some changes are likely, but probably not big ones.

Example Usage
nats-proxy gateway
nc, _ := nats.Connect(nats.DefaultURL)
gw, _ := nats_proxy.Wrap(h, 
  nats_proxy.WithNats(nc),
  nats_proxy.WithSubject("api"), // gateway root e.g. /
)

service connected to NATS via nats-proxy:

Since nats-proxy wraps http.Handler, existing web frameworks are compatible.

Let's mount an api to the path /api/sample.

h := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
  io.WriteString(w, "hello world")
})

nc, _ := nats.Connect(nats.DefaultURL)
nats_proxy.Wrap(h, 
  nats_proxy.WithNats(nc),
  nats_proxy.WithSubject("api.sample"), // e.g. /api/sample
)
http client
resp, _ := http.Get("http://127.0.0.1/api/sample")

For additional examples, see the examples package.

NATS subject

nats-proxy leverages the NATS subject to route requests. Given a gateway with the subject api and the following url:

http://localhost/a/b/c

the resulting subject would be

api.a.b.c
Example

In this example, let's suppose we want to set up an api gateway using nats-proxy backed by two NATS micro services, Foo and Bar with routes as follows:

/ - root path
    /foo - handled by Foo service
    /bar - handled by Bar service

We can define this topology in nats-proxy with the following subjects:

  • api - gateway subject, represents the root of the tree
  • api.foo - subject for Foo
  • api.bar - subject for Bar

Running Multiple Gateways

Let's suppose we would like to run multiple gateways in using a single NATS cluster. We might want to do this to handle different environments or different products. We can do this easily with nats-proxy by specifying a different root subject for the gateway.

For example:

nc, _ := nats.Connect(nats.DefaultURL)
staging, _ := nats_proxy.Wrap(h, 
  nats_proxy.Nats(nc),
  nats_proxy.Subject("api.staging"), // root subject for our staging environment 
)

Documentation

Overview

Package nats_proxy is a generated protocol buffer package.

It is generated from these files:

message.proto

It has these top-level messages:

Cookie
Message

Index

Constants

View Source
const (
	// DefaultSubject provides the name of the root subject nats-proxy will bind to
	DefaultSubject = "api"

	// DefaultTimeout specifies the maximum amount of time a request may take
	DefaultTimeout = time.Second * 10

	// DefaultQueue specifies the name of the queue for Conn.QueueSubscribe
	DefaultQueue = "service"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Cookie struct {
	Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
	Path  string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"`
}

func (*Cookie) Descriptor

func (*Cookie) Descriptor() ([]byte, []int)

func (*Cookie) GetPath

func (m *Cookie) GetPath() string

func (*Cookie) GetValue

func (m *Cookie) GetValue() string

func (*Cookie) ProtoMessage

func (*Cookie) ProtoMessage()

func (*Cookie) Reset

func (m *Cookie) Reset()

func (*Cookie) String

func (m *Cookie) String() string

type Filter

type Filter func(Handler) Handler

Filter allows filters to be applied after nats-proxy has transformed the request into a *Message

func (Filter) AndThen

func (f Filter) AndThen(h Handler) Handler

AndThen provides a convenience func to execute the handler

type Gateway

type Gateway struct {
	// contains filtered or unexported fields
}

Gateway is our http -> nats gateway

func NewGateway

func NewGateway(opts ...Option) (*Gateway, error)

NewGateway returns a new http to nats gateway with the options provided

func (*Gateway) ServeHTTP

func (p *Gateway) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler contract. Wraps messages into a *Message and performs a nats request

type Handler

type Handler func(ctx context.Context, subject string, message *Message) (*Message, error)

Handler publishes messages to nats and receives the response

func Chain

func Chain(h Handler, filters ...Filter) Handler

Chain folds a series of Filters with a Handler to construct a new Handler

func Nop

func Nop() Handler

Nop is an empty handler that echoes the provided message; useful for testing

func (Handler) Apply

func (fn Handler) Apply(ctx context.Context, subject string, message *Message) (*Message, error)

Apply is a helper function to make calls to the Handler more readable

type Message

type Message struct {
	Status  int32              `protobuf:"varint,1,opt,name=status" json:"status,omitempty"`
	Method  string             `protobuf:"bytes,2,opt,name=method" json:"method,omitempty"`
	Header  map[string]string  `` /* 132-byte string literal not displayed */
	Cookies map[string]*Cookie `` /* 134-byte string literal not displayed */
	Body    []byte             `protobuf:"bytes,5,opt,name=body,proto3" json:"body,omitempty"`
}

func (*Message) Descriptor

func (*Message) Descriptor() ([]byte, []int)

func (*Message) GetBody

func (m *Message) GetBody() []byte

func (*Message) GetCookies

func (m *Message) GetCookies() map[string]*Cookie

func (*Message) GetHeader

func (m *Message) GetHeader() map[string]string

func (*Message) GetMethod

func (m *Message) GetMethod() string

func (*Message) GetStatus

func (m *Message) GetStatus() int32

func (*Message) ProtoMessage

func (*Message) ProtoMessage()

func (*Message) Reset

func (m *Message) Reset()

func (*Message) String

func (m *Message) String() string

type Option

type Option func(*config)

func WithCookies

func WithCookies(cookies ...string) Option

WithCookies specifies the specific cookies that should be passed across nats

func WithFilters

func WithFilters(filters ...Filter) Option

WithFilters allows gateway filters to be specified; applies ONLY to Gateway

func WithHandler

func WithHandler(h Handler) Option

WithHandler allows the underlying handler to be specified; useful primarily for testing

func WithHeaders

func WithHeaders(headers ...string) Option

WithHeaders specifies http headers that should be passed across nats

func WithNats

func WithNats(nc *nats.Conn) Option

WithNats specifies the nats connection to use

func WithNopHandler

func WithNopHandler() Option

WithNopHandler provides an nop handler useful for testing; the content submitted will be echoed back

func WithNotFoundEnabled

func WithNotFoundEnabled(enabled bool) Option

WithNotFoundEnabled specifies whether or not the ```*nats_proxy.Router``` should respond with 404 Not Found for routes it's unable to handle

func WithQueue

func WithQueue(queue string) Option

WithQueue specifies the queue the nats subscribers should belong to

func WithSubject

func WithSubject(subject string) Option

WithSubject specifies the nats subject root to publish to

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout specifies how long a single request can take; defaults to ```nats_proxy.DefaultTimeout```

func WithUrl

func WithUrl(url string) Option

WithNats specifies the nats url to use

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router provides a wrapper over the standard http.Handler interface and acts as a bridge between the http.Handler and nats

func Wrap

func Wrap(h http.Handler, opts ...Option) (*Router, error)

Wrap an existing http.Handler with the specified options

func (*Router) Subscribe

func (r *Router) Subscribe(ctx context.Context) (<-chan struct{}, error)

Subscribe listens to the subject specified

Directories

Path Synopsis
cmd
examples
gin

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL