skip to content

Which io.rest-assured coordinate does a REST Assured test project depend on, and what comes with it?

level: juniorimportance: should knowfreq 62%

answer

  1. one coordinate covers the common case
  2. group id hyphenated, package is not
  3. json-path and xml-path ride along
  4. mappers optional, schema validator separate
  5. no runner in the dependency tree

basics

~20 s

The one coordinate io.rest-assured:rest-assured at test scope covers API testing; it brings json-path, xml-path, Groovy, Apache HttpClient and Hamcrest with it. Object mapping, JSON schema validation, Kotlin blocks and Spring support are separate artifacts, and no test runner is included.

solid answer

~40 s

For an HTTP suite you add exactly one dependency, `io.rest-assured:rest-assured`, at test scope. Note that the group id is hyphenated (`io.rest-assured`) while the package you import is not (`io.restassured`). That artifact declares `json-path` and `xml-path` as compile-scope dependencies, so `JsonPath` and `XmlPath` arrive automatically, together with Groovy, Apache HttpClient and Hamcrest. Everything else is a deliberate opt-in: the object mappers (Jackson, Gson, JAXB, Johnzon, Yasson) are declared optional, so `as(Turbine.class)` fails at runtime until you add one; `json-schema-validator`, `kotlin-extensions`, `spring-mock-mvc` and `spring-web-test-client` are separate coordinates. `rest-assured-all` is a shaded jar the docs offer for Java 9+ split-package trouble, and `rest-assured-bom` pins the io.rest-assured module versions and nothing outside that group. A JUnit or TestNG dependency is still yours to declare; REST Assured's own build lists JUnit only at test scope.

code

xml · 22 lines
xml
<dependency>
  <groupId>io.rest-assured</groupId>
  <artifactId>rest-assured</artifactId>
  <version>6.0.1</version>
  <scope>test</scope>
</dependency>

<!-- only if you call matchesJsonSchemaInClasspath -->
<dependency>
  <groupId>io.rest-assured</groupId>
  <artifactId>json-schema-validator</artifactId>
  <version>6.0.1</version>
  <scope>test</scope>
</dependency>

<!-- only if you deserialize the turbine payload -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.17.1</version>
  <scope>test</scope>
</dependency>

go deeper

for a junior

Be able to name the coordinate from memory: group io.rest-assured, artifact rest-assured, test scope. Know that json-path and xml-path come with it, and that you still declare your own test runner separately.

for a middle

Explain why the object mappers are optional dependencies and what the runtime message looks like when none is present. Be ready to say which extra coordinate a schema check or a Kotlin block requires.

for a senior

Show you can audit a real dependency tree: which io.rest-assured jars are present, which third-party libraries they share with the runner, and whether rest-assured-all is being used as a substitution rather than an addition.

for a principal

Own the policy. Decide whether the organisation imports rest-assured-bom, how one version is pinned across modules, and what the standing answer is for the shared libraries the BOM deliberately does not manage.

## One coordinate, and why the name has a hyphen in it REST Assured is published under the Maven group id `io.rest-assured`, hyphenated, while the classes you import live in the package `io.restassured`, with no hyphen. Getting that backwards is the most common first-day mistake, and because it fails during dependency resolution rather than at compile time, the message complains about a missing artifact rather than a missing class. For a suite that exercises a windfarm turbine-status service over HTTP, one declaration at test scope is enough: - `io.rest-assured:rest-assured` is the whole DSL — `given()`, `when()`, `then()`, request and response specifications, filters, authentication, logging and the matcher seam. - It declares `json-path` and `xml-path` as ordinary compile-scope dependencies, so `JsonPath` and `XmlPath` arrive with it. You list those separately only when you want the parsers **without** the HTTP client. - It also brings Groovy, `groovy-xml`, Apache HttpClient, `httpmime`, tagsoup and Hamcrest. None of those is optional: a GPath expression such as `turbines.find { it.serial == 'WTG-114' }` is compiled and evaluated as Groovy, and `body(path, matcher)` takes an `org.hamcrest.Matcher`. ## What each io.rest-assured artifact adds | Artifact | What it adds | When you need it | |---|---|---| | `rest-assured` | the DSL; pulls `json-path` and `xml-path` | any HTTP suite | | `json-path` / `xml-path` | the GPath parsers on their own | parsing without calling | | `json-schema-validator` | the `matchesJsonSchema*` matchers | schema assertions | | `kotlin-extensions` | the `Given { } When { } Then { }` blocks | writing in Kotlin | | `spring-mock-mvc`, `spring-web-test-client` | separate Spring entry points | Spring slice tests | | `rest-assured-all` | the module jars shaded into one | Java 9+ split-package trouble | | `rest-assured-bom` | `pom`-packaged version management | multi-module builds | ## The opt-ins that catch people out 1. **Object mappers are optional.** Jackson 3, Jackson 2, Jackson 1, Gson, JAXB, Johnzon, Yasson and the Jakarta JSON API are all declared with `<optional>true</optional>`, so none of them reaches your classpath through REST Assured. Deserialize a turbine payload with none of them present and you get `IllegalStateException: Cannot parse object because no JSON deserializer found in classpath.` — a runtime exception, not an assertion failure. 2. **`scribejava-apis` is optional too.** Only OAuth 1 and `oauth2(token, OAuthSignature.QUERY_STRING)` need it on the classpath; a plain bearer token through `auth().oauth2(token)` does not. 3. **`json-schema-validator` does not depend on `rest-assured`.** Its own dependencies are the underlying JSON schema library, Guava and Hamcrest. Adding it never pulls the DSL in, and omitting it turns `matchesJsonSchemaInClasspath` into a compile error rather than a runtime surprise. ## No runner comes in the box This is the part that decides how a suite is wired. REST Assured ships no test annotations, no lifecycle hooks and no reporting, and its main sources contain no reference to JUnit or TestNG at all — `junit-jupiter` appears in its own build only at test scope, for testing the library itself. The consequences are practical: - You declare your own runner, and its version is entirely your choice. - You own the shared libraries. Hamcrest in particular arrives at compile scope from `rest-assured` and is also a classic transitive of older test tooling, so it pays to know which copy wins. - Nothing about the DSL changes between runners. The same `given()...then()` chain compiles and behaves identically under JUnit 5 and TestNG; only the annotations around it differ. ## rest-assured-all and the BOM `rest-assured-all` is built with the Maven shade plugin over the `io.rest-assured` artifacts and published as a single jar. The project's Getting Started and FAQ pages present it as the drop-in replacement for `rest-assured` when Java 9+ split packages cause trouble. Treat it as a substitution: depend on `rest-assured-all` **instead of** `rest-assured`, never both, or the same classes land on the classpath twice. Its third-party dependencies are promoted rather than bundled, so Groovy, Apache HttpClient and Hamcrest still arrive transitively. `rest-assured-bom` is a `pom`-packaging bill of materials you import into dependency management. Its managed list is the project's own modules and nothing else: `rest-assured`, `rest-assured-all`, `rest-assured-common`, `json-path`, `xml-path`, `json-schema-validator`, `spring-commons`, `spring-mock-mvc`, `spring-web-test-client`, the Kotlin extension modules and the Scala modules. That makes it worth importing in a multi-module build so every module agrees on one REST Assured version, but it deliberately manages nothing outside the group — it will not pin Groovy, Hamcrest or Apache HttpClient for you. ## Putting it together for a turbine suite A module that calls `GET /api/turbines/{serial}/status`, asserts on `state` and `outputKw`, deserializes the payload into a `Turbine` record and checks it against a schema needs exactly four declarations: `rest-assured`, `json-schema-validator`, one object mapper, and a runner. Everything else follows transitively. Being able to say which of those four is transitive and which is deliberate — and why the library refuses to choose a runner for you — is what the question is really testing.

  • Why does the json-schema-validator module not pull rest-assured in with it?
    Its own dependencies are the underlying JSON schema library, Guava and Hamcrest — nothing from the DSL. `matchesJsonSchemaInClasspath` returns an ordinary Hamcrest matcher, so the module is usable anywhere a matcher is, and REST Assured simply accepts it inside `body(...)`. That means you declare both coordinates; adding one never implies the other.
  • When would you depend on json-path alone rather than rest-assured?
    When you only need to parse a document, not make a call — a helper that reads a stored turbine telemetry file, or a unit test asserting over a JSON string. `json-path` gives you `JsonPath.from(...)` and the GPath vocabulary without Apache HttpClient or the request DSL, which keeps the classpath of non-HTTP modules smaller.

saying these in an interview costs you the question

  • Thinks the Maven group id is io.restassured, matching the package name
  • Declares json-path and xml-path explicitly beside rest-assured
  • Expects response deserialization to work with no Jackson or Gson present
  • Believes rest-assured-bom pins Groovy, Hamcrest and HttpClient versions too
  • Thinks rest-assured brings a runner, so no JUnit dependency is needed
  • Assumes the JSON schema matchers ship inside the rest-assured artifact