In REST Assured, how do you fill the {orderId} placeholder in a request path?
answer
- curly braces make the path a template
- name them, or pass them positionally
- pathParam, pathParams, or trailing varargs
- index order decides the unnamed form
basics
~20 sREST Assured fills curly-brace path placeholders two ways. You name them on given with pathParam or pathParams, or pass values positionally as trailing arguments to the request method. Positional values fill the remaining placeholders left to right.
solid answer
~50 sA path template such as `/orders/{orderId}/signatures/{signatureNo}` carries two placeholders, and REST Assured refuses to send until each has a value. The **named** form declares them on the request: `given().pathParam("orderId", "BND-4417").pathParam("signatureNo", 12)`, or `pathParams(Map)` and the varargs `pathParams("orderId", "BND-4417", "signatureNo", 12)` when the values already travel together. The **unnamed** form is index-based: every verb has a `get(String path, Object... pathParams)` overload, so `get("/orders/{orderId}/signatures/{signatureNo}", "BND-4417", 12)` fills the slots left to right, and a `get(String, Map)` overload exists too. Values are plain `Object`s — an `Integer` is turned into its string form for you. The text inside the braces must match a named parameter exactly, casing included, or the request fails at send time. Naming pays off past two slots because it survives someone reordering the path, and one named value covers every occurrence of the same placeholder.
code
java · 19 linesimport static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.equalTo;
// Named: each placeholder bound by the text inside its braces
given()
.pathParam("orderId", "BND-4417")
.pathParam("signatureNo", 12)
.when()
.get("/orders/{orderId}/signatures/{signatureNo}")
.then()
.statusCode(200)
.body("status", equalTo("SEWN"));
// Unnamed: the same two slots, filled left to right
given()
.when()
.get("/orders/{orderId}/signatures/{signatureNo}", "BND-4417", 12)
.then()
.statusCode(200);go deeper
Be ready to write both forms from memory: pathParam on given(), or the values as trailing arguments to get(). Say out loud which placeholder each value lands in.
Explain that the path is a template scanned for braces, that a name must match the braces exactly, and that values are Objects converted to their string form for you.
Talk about readability at scale: which form the suite standardises on, and why a template that gains a segment breaks positional call sites silently until the request is actually sent.
Own the convention. Decide whether paths live as shared constants filled by name or inline per test, and what that choice costs when an API version reshapes paths across hundreds of cases.
## What a placeholder is in a REST Assured path The path you hand to `get`, `post`, `put`, `delete`, `patch`, `head`, `options` or `request(...)` is a **template**, not a finished URL. Anything between a `{` and the next `}` is a **placeholder**, and REST Assured will not send the request until every placeholder has a value. For a bookbindery order API the templates read `/orders/{orderId}` and `/orders/{orderId}/signatures/{signatureNo}`. Leaving the braces in the string — rather than concatenating an id into it — is what lets one literal path be reused across a dozen cases and read back intact in a log line. Two families of calls supply the values, and a single request may use both. ## The named form: pathParam and pathParams These are declared on `RequestSpecification`, so they belong in the `given()` half of the chain: - `pathParam(String name, Object value)` binds one placeholder: `given().pathParam("orderId", "BND-4417")`. - `pathParams(String first, Object firstValue, Object... rest)` takes alternating name/value pairs, as in `pathParams("orderId", "BND-4417", "signatureNo", 12)`. - `pathParams(Map<String, ?> map)` takes them as a map, which is what you want when the values arrive together from a fixture or from an earlier response. The name in the call must match the text inside the braces **exactly**. A placeholder written `{orderId}` is not filled by a parameter named `orderID`, and that mismatch is a runtime failure rather than a compile error. One named value covers every occurrence of that placeholder, so a template like `/orders/{orderId}/audit/{orderId}` still needs only one `pathParam("orderId", ...)` call. ## The unnamed form: index-based positional values Every request method also carries an `(String path, Object... pathParams)` overload and an `(String path, Map<String, ?> pathParams)` overload, so the values can travel with the path itself: - `get("/orders/{orderId}/signatures/{signatureNo}", "BND-4417", 12)` fills the two slots **left to right**. - The text inside the braces is never consulted in this form — position is the entire binding rule, which is why REST Assured calls these *unnamed* path parameters. - A `null` positional value is rejected before anything is built, with `IllegalArgumentException: Unnamed path parameter cannot be null (path parameter at index 0 is null)`. - The map overload is really the named form in disguise: `get("/orders/{orderId}", Map.of("orderId", "BND-4417"))` matches by key, not by position. ## Values are objects, not strings Both families take `Object`. `pathParam("signatureNo", 12)` and `get(".../{signatureNo}", 12)` are both legal, and REST Assured converts the value to its string form before splicing it into the path. That is worth more than it sounds: it keeps `String.valueOf(...)` noise out of the test, and an id held as a `Long` or a `UUID` in a fixture needs no ceremony at the call site. ## Choosing between the two forms | | named (`pathParam`) | unnamed (positional) | |---|---|---| | where it is written | in `given()`, before the verb | as trailing arguments to the verb | | what binds the value | the name inside the braces | the index of the placeholder | | survives reordering the path | yes | no | | reads well with one slot | verbose | ideal | | reads well with three or more | ideal | error-prone | The convention most suites settle on comes out roughly like this: 1. One placeholder and a literal value at the call site — use the positional form, because `get("/orders/{orderId}", orderId)` is hard to misread. 2. Two or more placeholders, or values computed earlier in the test — name them, so a reader can check `pathParam("signatureNo", 12)` against the template without counting arguments. 3. Values that arrive as a map from a data fixture — hand the map to `pathParams(Map)` and let the keys do the matching. ## What happens when the accounting is wrong REST Assured checks the count when the request is actually sent, not when you build the specification, and it throws `IllegalArgumentException` naming what it expected, what it received, and which placeholders were left over. A missed call site after a template gains a segment produces `Invalid number of path parameters. Expected 2, was 1. Undefined path parameters are: signatureNo.` The message is designed to be read rather than merely caught: the counts tell you which side is wrong, and the trailing lists tell you exactly which name or value is unaccounted for.
- What does REST Assured do when the same placeholder name appears twice in one path template?A single named value fills every occurrence, so `given().pathParam("orderId", "BND-4417").when().get("/orders/{orderId}/audit/{orderId}")` sends `/orders/BND-4417/audit/BND-4417`. The positional form behaves differently: each placeholder in turn consumes the next trailing value, so the same template would need two arguments rather than one.
- Can a placeholder appear in the query-string part of the path string you pass to get()?Yes. REST Assured scans the whole path string it is given, so `get("/orders?cloth={clothCode}", "MOROCCO")` fills the placeholder after the `?` as well, and it counts toward the same expected-versus-supplied accounting. Keeping query values out of the template is usually clearer, but the form is legal and turns up in suites that store whole URLs as constants.
saying these in an interview costs you the question
- Builds the URL by string concatenation instead of using a template
- Thinks queryParam or param can fill a curly-brace placeholder
- Assumes path values must already be Strings
- Expects an unfilled placeholder to be silently dropped from the URL
- Believes pathParams accepts only a Map, not name/value pairs