2

I want to create a "mock" server using Ratpack.

First, I'm reading from a folder and defining a list of pairs, each pair has:

  • A path
  • The mock response for that path

I want to launch a server that defines those routes and responses:


// this is already done; returns smth such as:
def getServerRules() {
  [ path: "/books", response: [...] ],
  [ path: "/books/42", response: [ title: "this is a mock" ] ],
  [ path: "/books/42/reviews", response: [ ... ] ],
  ...
]

def run() {
 def rules = getServerRules()
 ratpack {
   handlers {
     get( ??? rule.path ??? ) {
       render json( ??? rule.response ??? )
     }
   }
 }
}

Can I iterate over those rules in order to define a handler for each item somehow?

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
Manu Artero
  • 9,238
  • 6
  • 58
  • 73

1 Answers1

3

You can define all your handlers by iterating over a list of defined server rules, something like in this Ratpack Groovy script:

@Grapes([
        @Grab('io.ratpack:ratpack-groovy:1.5.0'),
        @Grab('org.slf4j:slf4j-simple:1.7.25'),
        @Grab('org.codehaus.groovy:groovy-all:2.4.12'),
        @Grab('com.google.guava:guava:23.0'),
])

import static ratpack.groovy.Groovy.ratpack
import static ratpack.jackson.Jackson.json

def getServerRules() {
    [
            [path: "", response: "Hello world!"],
            [path: "books", response: json([])],
            [path: "books/42", response: json([title: "this is a mock"])],
            [path: "books/42/reviews", response: json([])],
    ]
}

ratpack {
    handlers {
        getServerRules().each { rule ->
            get(rule.path) {
                render(rule.response)
            }
        }
    }
}

As you can see all handlers are defined inside for-each loop that iterates over predefined server rules. Two things worth mentioning:

  • don't start your URL paths with "/" in the beginning, otherwise endpoint wont get defined
  • if you want to return JSON response wrap your response body with ratpack.jackson.Jackson.json(body) method, similarly to what I did in the example

Output

curl localhost:5050
Hello World!

curl localhost:5050/books
[]

curl localhost:5050/books/42
{"title":"this is a mock"}

curl localhost:5050/books/42/reviews
[]

I hope it helps.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
  • nitpicking: you dont need the groovy-all and guava grabs? – cfrick Nov 07 '17 at 09:43
  • it's perfect. Thxs – Manu Artero Nov 07 '17 at 09:44
  • @cfrick I had to add them, otherwise Groovy script didn't start up correctly - https://gist.githubusercontent.com/wololock/4c35003e18905f1828957b0efc29ad85/raw/7573a6a35d30c4b1f89ee18bb46396df8c49dea9/gistfile1.txt – Szymon Stepniak Nov 07 '17 at 09:45
  • I ran it with a locally installed groovy and that only needs slf2j and ratpack. But, well, then better keep them. – cfrick Nov 07 '17 at 09:49
  • @cfrick I thought it might be my multimodule project and some classpath conflicts that have to resolved explicitly, but copying a script to `/tmp/ratpack.groovy` and running it with locally installed Groovy (via SDKMAN!) causes same exception: https://gist.githubusercontent.com/wololock/277fb66e45582a8c7db865be8103ba5f/raw/d4ea630fe217f89079eb8836c7f5ca8dabbc0015/gistfile1.txt That's pretty weird :/ – Szymon Stepniak Nov 07 '17 at 09:54