skip to content

In REST Assured, when does a request actually go to port 8080?

level: middleimportance: must knowfreq 56%

answer

  1. 8080 is not a blanket default
  2. only when the authority is localhost
  3. URL port beats an explicit port
  4. https with no port stays on 443
  5. DEFAULT_URI is http://localhost

basics

~20 s

REST Assured appends its default port of 8080 only when the target carries no port and its authority is exactly localhost. An explicitly set port always wins over it, and an https target with no port set stays on 443.

solid answer

~50 s

`RestAssured.DEFAULT_PORT` is `8080`, but it is not a blanket default. The port is resolved in order: a port written into the URL itself wins; failing that an explicit `given().port(9090)` or the static field is appended; failing that an `https` target is left alone and uses 443; and only then is 8080 appended, and only when the authority is exactly `localhost`. So on an allotment water-rota API, `given().baseUri("http://rota.allotment-water.test").get("/plots")` reaches port **80** — the library adds nothing — while a bare `get("/plots")` against the default base URI `http://localhost` reaches `http://localhost:8080/plots`. That first case is what makes the constant look universal: out of the box the base URI is `http://localhost`, so every getting-started example lands on 8080 and the rule stays invisible. Note the reverse trap too: `given().port(9090)` is ignored when the URL already carries a port, so `get("http://rota.allotment-water.test:8443/plots")` still goes to 8443. `port(0)` throws `IllegalArgumentException`.

code

java · 17 lines
java
import static io.restassured.RestAssured.given;

// -> http://localhost:8080/plots  (localhost authority, so 8080 is appended)
given().when().get("/plots").then().statusCode(200);

// -> http://rota.allotment-water.test/plots  (port 80: nothing is appended)
given().baseUri("http://rota.allotment-water.test")
.when().get("/plots").then().statusCode(200);

// -> http://rota.allotment-water.test:9090/plots  (explicit port applies)
given().baseUri("http://rota.allotment-water.test").port(9090)
.when().get("/plots").then().statusCode(200);

// -> http://rota.allotment-water.test:8443/plots  (the URL's own port wins)
given().port(9090)
.when().get("http://rota.allotment-water.test:8443/plots")
.then().statusCode(200);

go deeper

for a junior

Recall that 8080 is what a bare local request reaches, and that a real hostname needs the port supplied. Being able to say where a chain lands is enough at this stage.

for a middle

Walk the resolution order out loud: URL port, then explicit port, then the https case, then the localhost-only 8080. Naming the localhost carve-out is what separates a memorised default from an understood one.

for a senior

Show how you would diagnose a connection-refused run: print the assembled URI, confirm which of the four rules fired, and decide whether the port belongs in the base URI or in a per-request override.

for a principal

Take a position on where host and port live for the whole suite — one string that a target switch replaces, versus scattered port() calls — and on how a mis-targeted run should fail loudly rather than quietly hit a local address.

`RestAssured.DEFAULT_PORT` is `8080`, and almost every REST Assured tutorial repeats that "the default port is 8080". The constant is real; the sweeping reading of it is not. REST Assured resolves the port of a request through a short chain of conditions, and 8080 is only the last of them — reached in one narrow case. ## The resolution order Applied to whichever target the request ended up with, in this order: 1. **A port written into the URL wins.** If the base URI or the URL handed to the verb already carries `:8443`, nothing else is consulted. 2. **An explicitly set port is appended.** `given().port(9090)`, or the static field, supplies the port when the URL has none. 3. **An `https` target with no port set is left alone**, so TLS's own default of 443 applies. 4. **8080 is appended** when nothing above applied and the target's authority is exactly `localhost` (or the target is not fully qualified at all). 5. **Otherwise nothing is appended**, and the scheme's own default applies — port 80 for plain `http`. The consequence that surprises people is step 5. A fully qualified, non-localhost base URI with no port keeps no port, so it goes to 80, not 8080. ## Worked cases on one API | The chain | Where it lands | |---|---| | `get("/plots")` with nothing set | `http://localhost:8080/plots` | | `baseUri("http://rota.allotment-water.test").get("/plots")` | `http://rota.allotment-water.test/plots` — port 80 | | `baseUri("http://rota.allotment-water.test").port(9090).get("/plots")` | port 9090 | | `baseUri("https://rota.allotment-water.test").get("/plots")` | port 443, no port written | | `port(9090).get("http://rota.allotment-water.test:8443/plots")` | port 8443 — the URL wins | The first row is why the constant feels like a blanket default: the out-of-the-box base URI is `RestAssured.DEFAULT_URI`, the literal `http://localhost`, whose authority is exactly `localhost`. Every getting-started example therefore lands on 8080, and the rule that produced it stays invisible until the suite is pointed at a real host. ## Why the localhost carve-out exists The library was written for tests that boot a service in the same JVM or the same container on a conventional development port. Appending 8080 to `localhost` makes `get("/plots")` work with no configuration at all. Appending it to `https://rota.allotment-water.test` would instead break every request against a real deployment, so the rule is deliberately narrow. The `https` clause in step 3 exists for the same reason: an explicit port on a TLS endpoint is unusual, and forcing one would defeat the ordinary `443` case. It is worth separating the two constants involved, because they are easy to conflate. `RestAssured.DEFAULT_PORT` is the value 8080 that the localhost branch appends. `RestAssured.UNDEFINED_PORT` is `-1`, the sentinel meaning "nobody set a port", and it is what the resolution chain checks at every step rather than a value that ever reaches the wire. A port field holding `-1` is not a misconfiguration; it is the normal state of a request whose port comes from its URL or its scheme. ## Things that catch people out - **`given().port(...)` is silently ignored when the URL already has a port.** `given().port(9090).get("http://rota.allotment-water.test:8443/plots")` sends to 8443, and no warning is produced. - **The reverse also holds.** An explicit port is appended even to a fully qualified URL that carries none, so `given().port(9090).get("http://rota.allotment-water.test/plots")` reaches 9090. - **`port(0)` throws.** `RequestSpecification.port(int)` rejects anything below 1 other than the sentinel `RestAssured.UNDEFINED_PORT`, with an `IllegalArgumentException` reading "Port must be greater than 0". - **The published wiki is looser than the code here.** Its default-values page says a reset restores "standard port (8080)"; the field is actually restored to `UNDEFINED_PORT`, which then feeds the resolution chain above. Trust the behaviour, not the sentence. ## Practical consequences for a suite - If a suite works locally and gets connection refused against a deployed host, check the port before anything else — 8080 was almost certainly never being applied there. - Prefer writing the port into the base URI (`https://rota.allotment-water.test:8443`) when it is a property of the environment. That keeps host and port in one string that a single configuration switch can replace. - Reserve `given().port(...)` for the case it reads well in: a chain that must reach a different port on the same host, such as an admin endpoint on the water-rota service. - Print the assembled request URI once in a failing run — with `given().log().uri()` or a request-logging filter — rather than reasoning about the rule from memory. The library shows exactly which port it decided on. The compact form worth memorising: **the URL's own port beats an explicit port, which beats the https default, which beats 8080 — and 8080 only ever applies to `localhost`.**

  • Why does the same suite reach 8080 locally but port 80 against a deployed host?
    Locally the base URI is the default `http://localhost`, whose authority is exactly `localhost`, so REST Assured appends 8080. Once the base URI is a real hostname the carve-out no longer matches, no port is appended, and the plain `http` default of 80 applies. Set the port in the base URI or with `given().port(...)`.
  • Does given().port(9090) still apply when the verb is handed a full URL?
    Yes, provided that URL carries no port of its own: the explicit port is appended to it. If the URL already specifies a port, that port wins and the `port(...)` call is silently ignored. An `https` URL with no port and no explicit port set is left on 443.

saying these in an interview costs you the question

  • Says 8080 is the default port for every REST Assured request
  • Thinks given().port() always wins over a port written in the URL
  • Believes an https base URI with no port gets 8080
  • Assumes port 80 is impossible because a default is always applied
  • Claims the port must be set or the request will not be sent