InVision is a collaborative design company that’s growing into Golang. That being said, when we started doing web services, we looked at using one of the middleware libraries out there such as Alice and Negroni. We found them all interesting but decided to tackle it on our own. As we did that we realized that our library was pretty cool so we broke it out and open sourced it as Rye. I’ll present on the approach we took and some of the benefits of using Rye including integration with Statsd, Context and custom middleware handlers we’ve added such as CIDR validation and JWT validation.
2. WhoisInVision?
Design Better. Faster. Together.
2
Design Collaboration Cloud
Prototyping
Collaborative Asset Management
Project Management
Real-time Design Updates
Complete Product Design Process
Integrate with User Testing
Integrate with Sketch and Adobe Creative Cloud
01
02
03
04
05
06
07
08
3. 3
Middleware - What is it?
• Abused term in Software Engineering
• Hardware/Software
• Middle-tier?!
• Data pipelining
• Middleware - A definition
• A function in the HTTP pipeline with
access to the request and the response
• Lots of approaches
• Pipelines
• Wrapping
• Chaining
• Express.JS Middleware
• http://expressjs.com/en/guide/using-
middleware.html
Request comes into web server, In Golang, handlers receive the request as a passed
in parameter and the ResponseWriter for output.
1. REQUEST
A good usage of Middleware methods is a reusable way to accept and translate
cross-origin requests. Since you might do this on every call, it’s a great use.
1. MIDDLEWARE 1 (Accept CORS?)
APIs often require some kind of access-token as a verification of the calling
application. Once again, as a middleware, you can separate from your action.
1. MIDDLEWARE 2 (Check Access Token)
Logging lots of information about a request can be very helpful with debugging.
You may not want this in your action. This allows you to normalize logs.
1. MIDDLEWARE 3 (Log Route and Request Info)
Your action basically takes the format of a Middleware function and is often the end
of the pipeline with the response being written here.
1. DO YOUR STUFF!
4. 4
Golang Middleware: Negroni
• Not a full framework - a library - Familiar API
• Can be used with routing packages
• Lots of 3rd party middlewares
• https://github.com/urfave/negroni
6. 6
Golang Middleware: alice
• Very simple library
• TINY! (the smallest)
• Builds chain of middleware
• Supports any handler
• Must be handler function
• Transforms syntax from doing it
yourself
• https://github.com/justinas/alice
7. 7
Golang Middleware: Make-Your-Own
• So much choice?
• What do you need to do with Middleware?
• Custom pipeline?
• Complex requirements?
• Something that doesn’t fit?
• Simplicity!
• But, organization wide?
• Ref:
http://www.alexedwards.net/blog/making-and-using-middleware
8. 8
Introducing: Rye!
• Easy to configure
• Built-in Statsd per middleware
• Supports 1.7 Golang Context
• Out of the box Middlewares
• Access Token verification
• CIDR verification
• JWT verification
• CORS support
• Route logging
• Extensible
• Make a middleware easily
9. 9
SETUp
• Setup Statsd Client - If desired, can be passed as nil interface to config
• Setup Config Struct
• Create a new Middleware Handler
• Create multiple pipelines if desired
10. 10
Making a Handler
• Writing a handler is simple!
• Uses a custom type
(for a structured response)
• rye.Response allows you to
control StatusCode and
Error text specifically
• StopExecution will force a
stop in the chain
• Type is the same as a
regular handler except
for rye.Response
11. 11
STATS
• StatsD stats are optional, but if configured automatically added to every middleware execution!
• Uses “github.com/cactus/go-statsd-client/statsd”
• Prefix configured on the Statter and passed to MWHandler
• We include a counter, timing, and errors (status 500+)
• Works great with something like DataDog for metrics
12. 12
ACCESS TOKEN
• Compares header to list of tokens
• Configurable header name
• Could be managed at runtime
13. 13
CORS
• Allow Cross Origin calls easily
• Allow specific headers, methods and origins
• Defaults for working with development
• Origins: *, Methods: POST, GET, OPTIONS, PUT, DELETE
• Accept, Content-Type, Content-Length, Accept-Encoding,
X-CSRF-Token, Authorization, X-Access-Token
14. 14
CIDR
• Configure multiple CIDR filters
• CIDR notation: https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
• A failure produces a 401 Unauthorized
15. 15
JWT
• Easy JWT Validation
• Looks for “Authorization” header with a “Bearer” prefix
• Strips Prefix, Checks for JWT (returns 400 if not found)
• Uses “github.com/dgrijalva/jwt-go” to verify
• Drops JWT into Go Context (1.7) with key of [rye-middlewarejwt-jwt]
17. 17
USING CONTEXT
• Context is automatically added to the request scope
• Requires 1.7 Context - Built for the future with Go
• Unobtrusive
• Example! JWT Middleware adds JWT to the Context - retrieval is easy