Post on 17-Aug-2015
transcript
Quick Overview
• A high-‐throughput, reac=ve web framework for the JVM
• Built on Java 8 (required) and comes with a Groovy DSL
• Great support for microservices / Twelve Factor apps
• Rapid produc=vity
Quick Start
• Groovy DSL is the path of least resistance • App can be built into a standalone, runnable Groovy script
• Rapid prototyping
What is this doing?
• Imports the DSL via ratpack.groovy.Groovy.ratpack
• The closure supplied is the defini3on • Defini=on consists of serverConfig, bindings, and handlers
• App defini=on infers reasonable defaults for serverConfig and bindings
Handler Chain
• A pipeline for request processing • The “edge” of an applica=on • Defines request flow and terminal handlers • Handlers can be thought of in equivalent terms to servlets and servlet filters
Handlers
• Two types of handlers: request flow and terminal
• Request flow handlers provide flow control in processing
• Terminal handlers process and respond to a request
Terminal Handlers
• Bound to HTTP verb(s) and request path • Chain API provides seman=c methods for binding to verb
Method Descrip.on Usage
all Handler is executed for all requests within its chain
all { render “Hello World!” }
get(path) Handler for HTTP GET requests. Path op=onal.
get(“foo”) { render “Hello Foo!” }
post(path) Handler for HTTP POST requests. Path op=onal.
post(“foo”) { def json = request.body.text … }
put(path) Handler for HTTP PUT requests. Path op=onal.
put(“foo”) { def json = request.body.text … }
patch(path) Handler for HTTP PATCH requests. Path op=onal.
patch(“foo”) { def json = request.body.text ... }
delete(path) Handler for HTTP DELETE requests. Path op=onal.
delete(“:id”) { def id = request.pathTokens.id ... }
A Caveat to Handlers
• Only a single handler can be bound for any given HTTP request path
• You must use request flow mechanisms to bind mul=ple handlers for a path
Request Flow Handlers
• Terminal handlers get nested • Allow host binding, prefix binding, decision rou=ng, method rou=ng, content type nego=a=on
• Can be defined within the handler chain or handlers themselves
Prefix Handler
• Creates a sub-‐chain bound to a prefixed request path
• Allows handlers to be defined within the context of the prefix
• Makes it easy to scope a handler chain
The when Handler
• Creates a sub-‐chain bound to a prefixed request path
• Allows handlers to be defined within the context of the prefix
• Makes it easy to scope a handler chain
Method Rou=ng
• Nested handler type (handlers within a handler)
• Uses the byMethod call within a handler • Must be bound within an all handler type
Content Type Nego=a=on
• Nested handler type (handlers within a handler)
• Uses the byContent call within a handler • Routed-‐to according to request’s Accept header
• Chain for content type handlers • Seman=cs for common content types (json, xml, html, plainText)
Method Descrip.on
json Called when application/json is specified in Accept header
xml Called when application/xml is specified in Accept header html Called when text/html is specified in Accept header plainText Called when text/plain is specified in Accept header
type(String) Called when the provided string matches the Accept header
noMatch Called when the Accept header is specified, but no handler is
bound for the given type
• Caveat: the first handler in the byContent chain is favored when no Accept header is present
Content Type Nego=a=on
Project Structure
• OOTB Support for Gradle build system • App structure follows Java conven=ons • Groovy apps can s=ll be built as scripts • Apps can be defined from within a main class
Gradle Support
• Add the io.ratpack:ratpack-‐gradle:<version> to your buildscript classpath
• Apply the io.ratpack.ratpack-‐{groovy,java} plugin to your buildscript
• ./gradlew run to see your app in ac=on!
Framework Dependencies
• Use the plugin helper method to bring in framework deps
• Framework deps are resolved by their unqualified name
• As simple as specifying ratpack.dependency(name) in dependencies block
Main Class Apps
• Any project can build a main class and use that as the entry point
• Use the ratpack.server.RatpackServer factory to define your applica=on
• Java 8 apps must use a main class
Dependency Injec=on
• DI in Ratpack is abstracted through the Registry
• Request handling code is FP style, so should remain stateless
• The Context given to each handler allows resolu=on of components
Dependency Injec=on
• OOTB support for Guice and Spring Boot • Groovy DSL has Guice fixtures pre-‐baked • The bindings block allows you to bind components in your app
Dependency Injec=on
• Groovy DSL: Components injected into handlers through varargs
• Java API: components are resolved through Context.get(Class)
• Note that non-‐Groovy apps need to include the ratpack-‐guice framework dependency
Registries
• Registries can be built on-‐the-‐fly within the handler chain
• Latest binding will be resolved first • Allows apps to register and resolve components according to proper=es of a request
Tes=ng
• Ratpack provides fixtures for func=onal, integra=on, and unit tes=ng
• Can quickly get high test coverage with li_le effort
• EmbeddedApp fixture can be integrated to ameliorate hard-‐to-‐test or legacy apps
Non-‐Blocking Paradigm
• Ratpack uses NIO to garner high throughput • Maintains discrete request-‐taking and blocking thread pools
• Request-‐taking threads must not block • Blocking APIs are able to be made async through the Context.blocking() mechanism
Building Async APIs
• Build your APIs around Ratpack Promise types • This gives you flexibility in determining in processing capacity (blocking/computa=on)
• Promises ensure that the Ratpack knows when your app is async processing
Reac=ve Programming
Reac3ve programming is a technique by a processing func3on requests data from a
producing func3on, a single element at a 3me. Mul3ple elements are delivered through a pipeline, wherein one or many func3ons can
affect the flow and form of data.
Reac=ve Programming
The request for data starts here
Transforming func=on Call for a data element
Call for a data element
Call for a data element
Filtering func=on
Producing func=on (will send elements down the pipeline when requested)
Reac=ve Programming
• Data is not “observed” by down-‐pipeline func=ons un=l the above-‐pipeline func=ons supply it
• Push vs. Pull data element retrieval methodology
• Best suited for async processing, where data is gathered on-‐demand (not in advance)
Reac=ve Programming
• Promises are reac=ve, in that they send data only when it is requested
• Promises will only ever “emit” a single item into the processing pipeline (whether it be a list of data elements or a single data element itself)
Reac=ve Programming
• Ratpack has extensive support for interopera=ng with RxJava
• Provides RxJava with a scheduler for processing work from Observables
• Observables can emit one or more data elements through the pipeline to cons=tute a “stream” of data
• Ideal for robust async API layers
Configura=on
• Support for building typed configura=on models from a variety of sources
• Configura=on can come from JSON, YAML, Java Proper=es
• Microservice and produc=on configs can pull configura=on from sys props and environment variables
Addi=onal Framework Features
• Non-‐blocking/Async HTTP client • Support for Hystrix for fault tolerance across microservices
• Database connec=on pooling (HikariCP) • Sessions and Cookies • Security (Pac4j) • Content serving (built-‐in and Asset Pipeline) • Metrics (CodaHale) • Asynchronous health checks
Packaging
• Builds leverage the Gradle applica=on plugin • Na=ve support for crea=ng tar or zip distribu=on packages for deployment
• Can be overlayed with the Shadow Jar plugin to build “fat jars”
• Perfect for cloud-‐na=ve microservice deployments
So Why Should I Care?
• Ratpack is FAST • A single instance of Ratpack can support up to 800,000 concurrent requests per second* – h_ps://gist.github.com/danveloper/db888be3519966976368
• Provides applica=on structure to non-‐blocking underpinnings
• App packages are standalone, runnable, and small