Skip to main content

REST Adapter

The REST adapter targets JSON APIs. It supports all HTTP verbs, request body serialization, bearer token authentication, typed response deserialization, and Promise<T> for passing data between steps.

Setup

var rest = builder.RestAdapterBuilder()
.WithBaseUrl(new Uri("http://localhost:8080"))
.Build();

The builder is accessed via the TransitionBuilder extension method builder.RestAdapterBuilder() provided by Xcepto.Rest.

HTTP verbs

rest.Get("/resource")
rest.Post("/resource")
rest.Put("/resource")
rest.Patch("/resource")
rest.Delete("/resource")

All methods also accept a Func<string> for lazy path evaluation.

Retry behavior

GET, PUT, DELETE are retried — evaluateConditionsForTransition is polled until all assertions pass or the timeout expires.

POST, PATCH execute once in onEnter — if an assertion fails, the test fails immediately.

Assertions

rest.Get("/status")
.AssertSuccess() // 2xx
.AssertClientFailure() // 4xx
.AssertServerFailure() // 5xx
.AssertThatResponseStatus(
status => status == 201) // custom status
.AssertThatResponseContentString(
body => body.Contains("active")) // body predicate
.AssertThatResponse(response => { // full HttpResponseMessage
if (response.StatusCode != HttpStatusCode.OK)
throw new XceptoTestFailedException("Expected 200");
});

Multiple assertions can be chained on the same step — all must pass for the state to transition.

Request body

rest.Post("/shipment/accept")
.WithRequestBody(() => new AcceptShipmentRequest(50))
.AssertSuccess();

The supplier is evaluated lazily at execution time, not at step registration time.

Typed response deserialization

rest.Post("/shipment/accept")
.WithRequestBody(() => new AcceptShipmentRequest(50))
.WithResponseType<AcceptShipmentResponse>()
.AssertThatResponse(r => r.Amount == 50);

WithResponseType<T>() deserializes the response body into T and adds a typed assertion overload.

Bearer token authentication

rest.Get("/api/me")
.WithBearerTokenClient(() => token)
.AssertSuccess();

The token supplier is evaluated lazily — it can reference a Promise value resolved by a previous step. See Patterns → Promise.

Promise — typed response

Use promiseResponse() to capture a typed response and pass it to a later step:

Promise<TokenResponse> token = rest.Post("/auth/login")
.WithRequestBody(() => new LoginRequest(username, password))
.WithResponseType<TokenResponse>()
.PromiseResponse();

rest.Get("/api/me")
.WithBearerTokenClient(() => token.Resolve().AccessToken)
.AssertSuccess();

See Patterns → Promise for the full pattern.

Query parameters

rest.Get("/search")
.AddQueryArgument(() => new[] { "q", searchTerm })
.AddQueryArgument(() => new[] { "limit", "10" })
.AssertSuccess();