Ratpack Web Framework
-
Upload
daniel-woods -
Category
Technology
-
view
1.516 -
download
3
Transcript of Ratpack Web Framework
![Page 1: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/1.jpg)
http://www.ratpack.io Dan Woods
#ratpack #learningratpack
![Page 2: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/2.jpg)
• Member of the Ratpack core team
• Work at Netflix
• Writing Learning Ratpack for O’Reilly
• Follow me on Twitter: @danveloper
![Page 3: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/3.jpg)
• A full-stack, high throughput, non-blocking web framework
• Built entirely on Java 8
• Specialized support for writing apps in Groovy
![Page 4: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/4.jpg)
• Groovy has come a long way over the last few years…
• Static compilation and (optional) compile time type checking
• Excellent language for writing concise DSLs • DSLs can be statically compiled!
Why Groovy?
![Page 5: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/5.jpg)
• Groovy’s three compilation modes give applications a lot of flexibility
• Parallels Java performance using Invoke Dynamic or Static Compilation
• Pick-and-choose static or dynamic, depending on the use-case!
Why Groovy?
![Page 6: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/6.jpg)
• Requires Groovy 2.3.6+
• Utilize advanced static compilation and type checking features of Groovy, like @DelegatesTo
• Allows you to define your application structure in a ratpack.groovy file
Why Groovy?
![Page 7: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/7.jpg)
@GrabResolver(name='netty', root='http://clinker.netty.io/nexus/content/repositories/snapshots')!@Grab('io.ratpack:ratpack-groovy:0.9.13-SNAPSHOT')!!import static ratpack.groovy.Groovy.ratpack!!ratpack {! handlers {! handler { ! response.send ”Hello World!"! }! }!}!
Simple Groovy Script*
* @GrabResolver will not be required after 4.1.0-Beta4 is published; * Ratpack 0.9.13 will be released on Feb 1, 2014
![Page 8: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/8.jpg)
• There are no plugins in Ratpack, instead the framework provides functionality through modules
• Modules are built in Guice*
• DI is an abstraction in Ratpack, so even though the framework uses Guice, you don’t have to
* h$ps://github.com/google/guice
![Page 9: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/9.jpg)
• A set of composable libraries for building unopinionated, rich web applications
• Pick-and-choose what aspects of the framework you want
• No lock-in to a single way of doing things
![Page 10: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/10.jpg)
• Emphasis on Performance and Efficiency in both applications and development experience
• Hot reloading is available during development time
• Beautiful development-time error pages
• Extreme emphasis on developer testing, especially functional and integration
• Support for mocking nearly all aspects of the framework
![Page 11: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/11.jpg)
Example of a development-time error:
![Page 12: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/12.jpg)
• Convention over configuration taken too far doesn’t let you wire things together
• Ratpack makes wiring modules a “one-liner”, so there’s not a lot of work to get new features integrated
• Out of the box support for Guice and Spring (Spring Boot) DI
![Page 13: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/13.jpg)
• Gradle integration makes building robust projects easy to do
• Simple apps can be run entirely through the Groovy command-line
![Page 14: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/14.jpg)
buildscript { repositories { jcenter() maven { url "http://oss.jfrog.org/oss-snapshot-local" } maven { url "http://clinker.netty.io/nexus/content/repositories/snapshots" } } dependencies { classpath 'io.ratpack:ratpack-gradle:0.9.13-SNAPSHOT' } } apply plugin: 'io.ratpack.ratpack-java'
Simple Gradle Build Script*
* Ratpack 0.9.13 will be released on Feb 1, 2014
![Page 15: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/15.jpg)
• Any non-trivial application needs build and packaging capabilities
• The Ratpack Gradle plugin provides all the fixtures to support building web application projects
![Page 16: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/16.jpg)
• Ratpack is built on Netty, which provides the infrastructure for highly performant, non-blocking networking
![Page 17: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/17.jpg)
• Netty is an extremely mature, super low-level networking library
• Excellent documentation, very involved community
• Heavy emphasis on high throughput and performance
![Page 18: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/18.jpg)
• Netty provides the infrastructure for non-blocking networking, but doesn’t help much in the way of web application structure
• Provides an asynchronous API for working with network data (including HTTP)
![Page 19: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/19.jpg)
• Computers “think” very good in asynchronous terms; humans do not…
• Without app structure, programming toward this paradigm is difficult
• Ratpack ensures the most performant structures of Netty are being utilized, while providing a sensible app structure and programming model
![Page 20: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/20.jpg)
• Ratpack provides applications with a Netty-based, non-blocking HTTP client
• Can be used to integrate with external RESTful services
• Utilizes the same event loop as the server, so resources are appropriately utilized
• Provides a robust API for programmatically crafting requests
![Page 21: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/21.jpg)
Above all else…
Ratpack is your GATEWAY DRUG
to non-blocking
![Page 22: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/22.jpg)
![Page 23: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/23.jpg)
• The JVM doesn’t have any concept of continuations, so the only option we have is asynchronous APIs
• Async APIs allow callers to provide a completion handler (or callback), which is to be invoked when some processing has finished
• There is no temporal relationship between the caller and the invocation of the callback
![Page 24: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/24.jpg)
handler { req, res ->! ... (1) do some work ...! ! async {! ... (2) do some async work ...! }! async {! ... (3) do some more async ...! }! ! ... (4) send response ...!}!
(1) – Definitely finishes first (2) – May finish before or after (3)
and (4)
(3) – May finish before or after (2) or (4)
(4) – May finish before or after (2) or (3)
Async APIs create non-determinism in control flow
![Page 25: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/25.jpg)
• The temporal disconnect creates non-determinism in request processing
• This is a big problem for web applications, because they demand a deterministic control flow
• Ratpack provides the concept of an Execution, which creates determinism in asynchronous processing
![Page 26: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/26.jpg)
handler { req, res ->! ... (1) do some work ...! ! async {! ... (3) do some async work ...! }! async {! ... (4) do some more async ...! }! ! ... (2) send response ...!}!
(1) – Definitely finishes first (3) – Definitely finishes third
(4) – Definitely finishes fourth
(2) – Definitely finishes second
Ratpack creates a deterministic control flow
![Page 27: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/27.jpg)
• Through Ratpack’s promise API, the Execution is able to schedule async segments to be invoked after the handler code has finished
• Promise API ensures that developers can work with asynchronous processing in a sensible way
![Page 28: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/28.jpg)
• In non-blocking, it is of paramount importance to not block the thread
• Since a single thread is handling processing
for many clients, blocking one blocks all • Need to adopt libraries that are non-blocking
or provide async APIs • This is not always practical…
![Page 29: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/29.jpg)
• Not all interfaces are able to be non-blocking or asynchronous
• Most non-blocking frameworks force you to be either entirely async or wholesale define your handlers as blocking
• This is limiting and makes it difficult to work with legacy APIs or those not crafted for non-blocking work
• Ratpack gives you a mechanism to define blocking execution segments in your handler code
![Page 30: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/30.jpg)
handler(r -> (ctx) -> { ModelDAO dao = ctx.get(ModelDAO.class); ctx.blocking(() -> dao.load(ctx.getPathTokens().get("id"))) .then(model -> { ... do some work with the data ... ctx.render(model); }); })
Handler with blocking operation
![Page 31: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/31.jpg)
• Blocking operations are scheduled to an I/O bound thread pool
• Once the blocking operation is completed, the data is then returned to the request taking thread, where processing can finish
• Blocking operations are invoked when they are subscribed to in the request-taking thread
![Page 32: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/32.jpg)
...
ctx.blocking(() -> { ... do some blocking io ...
return result; }).then(result -> { ... subscribe to the blocking promise ...
... process in the request-taking thread ... }) ...
Blocking with a subscription
![Page 33: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/33.jpg)
• Data is being delivered to web consumers in an increasingly real time way
• Web applications must be able to support streaming protocols like SSE and WebSockets
• Ratpack has built-in fixtures that make it easy to develop real-time web applications
![Page 34: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/34.jpg)
• Because of its non-blocking nature, Ratpack can support a high volume of concurrent real-time streams
• Valuable in app-to-app communication too, where a consumer wants to be reactively informed about some data
• Ratpack’s HTTP client also supports reading streams of data from external producers, making stream processing a great integration
![Page 35: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/35.jpg)
![Page 36: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/36.jpg)
• Ratpack applications are defined through a handler chain
• Handler chain is a programmatic construct for managing the flow of request data
• Handlers can be bound to request path routes and HTTP verbs
![Page 37: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/37.jpg)
import static ratpack.groovy.Groovy.ratpack!!ratpack {! handlers {! get {! response.send "I'm the default route!"! }! get("route1") {! response.send "I'm in route1"! }! get("route2/:param") {! response.send "I'm in route2 and received param: ${pathTokens.param}"! }! }!}!
Handler chain in a Ratpack Script-backed app
![Page 38: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/38.jpg)
RatpackServer.start(b -> b .config(ServerConfig.noBaseDir()) .handlers(chain -> chain .get(ctx -> ctx.getResponse() .send("I'm in the default route!")) ! .get("route1", (ctx) -> ctx.getResponse() .send("I'm in route1!")) ! .get("route2/:param", (ctx) -> ctx.getResponse() .send(String .format(” received param: %s", ctx.getPathTokens().get("param")))) ) );"
Handler chain in using Java 8 APIs
![Page 39: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/39.jpg)
• Ratpack applications are defined through a handler chain
• Handler chain is a programmatic construct for managing the flow of request data
• Handlers can be bound to request path routes and HTTP verbs
![Page 40: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/40.jpg)
handlers {! get { ... }! get("route") { ... }! ! post { ... }! post("route") { ... }! ! put { ... }! put("route") { ... }! ! delete { ... }! delete("route") { ... }! ! patch { ... }! patch("route") { ... }!}!
Semantic handler API for binding to HTTP verbs and routes
![Page 41: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/41.jpg)
• Handlers can be nested within a route… handlers { prefix("api") { ModelDAO dao -> get { blocking { dao.getAll() }. then { models -> render JsonOutput.toJson(models) } } post { Model model = parse(fromJson(Model)) blocking { dao.save(model) }. then { m -> render m } } put(":id") { blocking { dao.load(pathTokens.id) }. map { model -> model.merge(parse(fromJson(Model))) }. blockingMap { model -> dao.save(model) }. then { model -> render model } } } }!
![Page 42: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/42.jpg)
• There’s a special handler type for serving static assets from the app’s baseDir!
• Static assets must be defined as the last handler in the chain
• Can be scoped to routes
![Page 43: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/43.jpg)
• Use the assets handler to serve static content
handlers { prefix("api") { get { response.send "some API data" } } assets("public", "index.html”) }!
![Page 44: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/44.jpg)
• You can also use a handler with byMethod to perform common processing within a route…
handlers { handler("api") { ModelDAO dao -> dao.beginTransaction() byMethod { get {} post {} put {} delete {} } dao.endTransaction() }!}!
![Page 45: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/45.jpg)
• Can discriminate on content type, allowing you to build HyperMedia APIs…
handlers { handler { byContent { json { response.send(toJson([msg: "regular json"])) } xml { response.send(...) } type("application/vnd.app.org+json;v=1") { response.send(toJson([newmsg: "hypermedia json"])) } } } }!
![Page 46: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/46.jpg)
• Handlers define the edge of your application
• In Servlet API terms, handlers can be thought of as a marriage between filters and servlets
• Allows request introspection and programmatic injection of handler chain
![Page 47: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/47.jpg)
• This allows handlers to be constructed and dependency injected, etc…
class UserHandler implements Handler { private final String message UserHandler(String message) { this.message = message } @Override void handle(Context context) !
!throws Exception { context.response.send(message) } }!
ratpack { bindings { bindInstance(new UserHandler("user handler")) } handlers { handler { UserHandler userHandler -> if (request! .headers.contains("X-Routing-Header")) { def routingHeader = request! .headers.get("X-Routing-Header") if (routingHeader == "user") { insert(userHandler) } } next() } get { response.send "default system handler" } } }!New Handler is
programma1cally inserted into the processing chain
![Page 48: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/48.jpg)
![Page 49: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/49.jpg)
• Dependency injection is an abstraction in Ratpack, through the concept of a Registry
• Components are bound to, and resolvable from, a Registry instance
• Registries can be backed in a DI framework
![Page 50: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/50.jpg)
• Out of the box support for Guice and Spring Boot
• Registries can be inherited, allowing components to be resolved in a cascading manner
• Every request context gets a registry that components can be extracted from
![Page 51: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/51.jpg)
• In a Groovy script that uses closures as handlers, the variable arguments to that closure are “injected” from the registry
• In Java 8, they are able to be resolved from the request context object
![Page 52: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/52.jpg)
• You don’t need to use a DI framework to get injection support, you can build your own registry from objects you construct…
public static void main(String[] args) throws Exception { Registry registry = Registries.registry() .add(new ModelDAO()).add(new DB()).build(); RatpackServer.start(spec -> spec .config(ServerConfig.noBaseDir()) .handlers(chain -> { chain.register(registry); chain.handler(":id", ctx -> { ModelDAO dao = ctx.get(ModelDAO.class); ctx.blocking(() -> dao.load(ctx.getPathTokens().get("id"))) .then(ctx::render); }); }) ); }!
![Page 53: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/53.jpg)
• Variables arguments to Groovy closure handlers are resolved from the registry
def myRegistry = Registries.registry() .add(new ModelDAO()) .build() ratpack { handlers { register(myRegistry) prefix("api") { get(":id") { ModelDAO dao -> render dao.load(pathTokens.id) } } assets("public", "index.html”) } }!
![Page 54: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/54.jpg)
• In Groovy, you get a bindings block, which you can use to bind components to the Registry. With Guice, annotations can be used to Inject
class UserHandler implements Handler { private final ModelDAO dao @javax.inject.Inject!
UserHandler(ModelDAO dao) { this.message = message } @Override void handle(Context ctx) !
!throws Exception { ctx.blocking {! dao.getAll()!
} then { ctx.render(it) } } }!
ratpack { bindings { binder { b -> b.bind(ModelDAO).in(Scopes.SINGLETON) b.bind(UserHandler).in(Scopes.SINGLETON) } }! handlers { handler { UserHandler userHandler -> if (request! .headers.contains("X-Routing-Header")) { def routingHeader = request! .headers.get("X-Routing-Header") if (routingHeader == "user") { insert(userHandler) } } next() } get { response.send "default system handler" } } }!
Can get a handle on a Guice binder to perform
annota1on-‐based Injec1ng
![Page 55: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/55.jpg)
• Likewise, a Guice Module can be “added” to the registry…
ratpack { bindings {! // Any Guice module can be added this way! // this is how Ratpack modules are" // introduced... " add(new SqlModule()) }! handlers { ...! } }!
![Page 56: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/56.jpg)
• Spring application context can be used to back a registry using the ratpack.spring.Spring class
h>p://www.ratpack.io/manual/0.9.13/api/ratpack/spring/Spring.html
![Page 57: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/57.jpg)
• Like handlers, registries can be programmatically registered into the handler chain based on request data
• Can allow your app to resolve components specific to the context of a request
![Page 58: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/58.jpg)
• Likewise, a Guice Module can be “added” to the registry…
def baseRegistry = Registries.registry() .add(new ModelDAO("jdbc:mysql://default")) .build() def cust1Registry = Registries.registry() .add(new ModelDAO("jdbc:mysql://cust1")) .build() ratpack { bindings { bindInstance(new DefaultDevelopmentErrorHandler()) } handlers { handler { next(get(PublicAddress).getAddress(it).host == "cust1" ? cust1Registry : baseRegistry) } prefix("api") { get(":id") { ModelDAO dao -> render blocking { dao.load(pathTokens.id) } } } assets("public", "index.html”) } }!
![Page 59: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/59.jpg)
![Page 60: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/60.jpg)
• Including framework modules in your Gradle based project is really easy
• Can utilize helper methods from the Ratpack Gradle plugin to include named modules
• Allows framework versions to stay in sync
![Page 61: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/61.jpg)
• The Ratpack Gradle plugin provides the ratpack.dependency() helper
...!!dependencies { compile ratpack.dependency("jackson”) compile ratpack.dependency(”rxjava”)! compile ratpack.dependency(”codahale-metrics”)! testCompile ratpack.dependency(”remote-test”) !
}!!...!
![Page 62: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/62.jpg)
• Including framework modules in your Gradle based project is really easy
• Can utilize helper methods from the Ratpack Gradle plugin to include named modules
• Allows framework versions to stay in sync
![Page 63: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/63.jpg)
• Static fixtures for mapping a multitude of external and environmental configuration sources to POJOs
Configuration Module: ratpack-config
// build.gradle"dependencies {! ... compile ratpack.dependency(”config”)! ... }!
import ratpack.config.*;!!ConfigurationData configData = Configurations.config() .yaml(Main.class.getResource("/app.yml")) .json(Main.class.getResource("/app.json")) .props("/etc/app/file.properties") .sysProps() .env() .build();!!
ServerConfig config = configData! .get("/server", ServerConfig.class); RatpackServer.start(spec -> spec .config(config) .handlers(...) );!
// classpath:/app.yml"server:! port: 8080!!
myAppStuff:! anyConfigData: 1234!
![Page 64: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/64.jpg)
• Environment-derivable configuration follows the principle of the Twelve Factor App
Great Support for building MICROSERVICES!!
![Page 65: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/65.jpg)
• NetflixOSS Hystrix support, via the ratpack-hystrix module
• Calls to remote services can be made fault tolerant
• Ability to stream Hystrix metrics to the Hystrix Dashboard
Great Support for building MICROSERVICES!!
![Page 66: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/66.jpg)
• The ratpack-hikari module uses HikariCP to create a super fast pooled SQL DataSource
• Can be used in conjunction with Groovy SQL to query databases
• Configurable using the fixtures from the ratpack-config module
Great Support for DATABASES!!
![Page 67: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/67.jpg)
• The ratpack-jackson module provides request data parsing and object rendering from and to JSON
• Data can be worked with in free-form nodes, or bound to command objects
• Arbitrary models can be rendered as JSON using simply context.render(obj)!
Great Support for DATA BINDING!!
![Page 68: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/68.jpg)
• Ratpack’s Promise API is an implementation of Reactive Streams Specification
• The ratpack-rxjava module provides a bridge between a Ratpack Promise and an RxJava Observable
• The ratpack-reactor module allows data to be processed using Project Reactor
Great Support for REACTIVE PROGRAMMING!!
![Page 69: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/69.jpg)
• View templates can be rendered through a variety of means
• Support for server-side templating with Handlebars, Thymeleaf, Groovy Templates, and Groovy Markup
• Ongoing work to integrate @davydotcom’s asset-pipeline, which will give robust support for all types of static content
Great Support for FULL-STACK FEATURES!!
![Page 70: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/70.jpg)
![Page 71: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/71.jpg)
• Ratpack has been built from the ground-up with testing considered at every turn
• Even more-so – considering testing from the perspective of the developer
• The concept of the Registry gives the framework control over components
• Makes it easy to provide fixtures for mocking and stubbing data
![Page 72: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/72.jpg)
• The EmbeddedApp class from the ratpack-test module supports functional and integration testing
• Can be used to test an application module or a subset of handlers and functionality
• Can be used outside of Ratpack too!
![Page 73: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/73.jpg)
• Spock is the choice framework, though there’s no strict integration there
• Functional tests are easy to bootstrap and the TestHttpClient helper makes it easy to programmatically craft test calls
![Page 74: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/74.jpg)
• Great resource for seeing Ratpack’s testing in action is the example-books project
• Rus Hart keeps this up to date with changes to the framework.
• https://github.com/ratpack/example-books
![Page 75: Ratpack Web Framework](https://reader033.fdocuments.in/reader033/viewer/2022052700/55a933e51a28ab30368b4873/html5/thumbnails/75.jpg)
Twitter people to follow:!!• @ldaley!• @rus_hart!• @varzof!• @Lspacewalker!• @marcinerdmann!• @ratpackweb!• @davydotcom!• @johnrengelman!• @rfletcherEW!• @beckje01!