HATEOAS Concept
Introduction
HATEOAS is one of the least understood concepts in REST. Many developers and testers work with REST-style APIs every day, using HTTP methods, JSON responses, resource URIs, and status codes, but never encounter a fully hypermedia-driven API. Because of this, HATEOAS often appears only in interviews, architecture discussions, or advanced REST design conversations. Still, it is an important concept because it explains one of the deeper ideas behind REST: clients should be able to discover available actions from the responses they receive.
HATEOAS stands for Hypermedia as the Engine of Application State. It is part of the uniform interface constraint in REST. The core idea is simple: instead of requiring the client to hardcode every possible endpoint and transition, the server includes links in the response that tell the client what it can do next. A client asks for a resource, receives a representation, reads the links inside that representation, and follows one of those links for the next action.
This is similar to how people use websites. When you open an online shopping site, you do not manually type every URL for products, cart, checkout, orders, and profile. The page shows links and buttons that guide your next step. HATEOAS applies that idea to APIs. The API response itself includes hypermedia controls, such as links to the current resource, related resources, next page, previous page, update action, delete action, or payment action.
For API testers, HATEOAS matters because it affects response validation, role-based behavior, discoverability, link accuracy, workflow testing, and API evolution. If an API claims to implement HATEOAS, testers must validate not only data fields, but also links, relationship names, allowed actions, authorization-sensitive links, pagination links, and broken-link behavior. This article explains HATEOAS in a practical way so testers can understand what it is, how it works, when it is useful, and how to test it.
What Is HATEOAS?
HATEOAS is a REST principle where the server includes hypermedia links in API responses to guide the client toward available resources and actions. Instead of the client knowing every endpoint in advance, the client starts from an entry point and discovers next actions from response links. These links are part of the representation returned by the server.
A simple definition is this: HATEOAS means a REST API includes hyperlinks in its responses so clients can discover available actions dynamically. The client does not only read data; it also reads the navigation options provided with that data.
For example, when a client retrieves user 101, the response may include user data plus links to the same user, the user's orders, update action, and delete action. The client can follow the links instead of constructing every URL from hardcoded knowledge.
Full Form of HATEOAS
HATEOAS stands for Hypermedia as the Engine of Application State. The phrase means that hypermedia controls, such as links, drive the client's movement through application states. A client moves from one state to another by following links returned by the server.
In a shopping API, a cart response may include a checkout link only when the cart is ready for checkout. An order response may include a cancel link only when cancellation is still allowed. A paginated product list may include next and previous links depending on the current page. The links are not decoration. They describe valid next transitions.
Why HATEOAS Was Introduced
Without HATEOAS, clients usually hardcode endpoint knowledge. A client must know that users are at /users, one user is at /users/101, orders are at /users/101/orders, updates use /users/101, and deletes use the same path with DELETE. This works, but it couples the client tightly to the API's URI structure.
With HATEOAS, the client can know a starting endpoint and then discover related actions dynamically. The server can include links based on resource state, user permissions, and available transitions. This reduces the amount of prior endpoint knowledge required in the client.
HATEOAS was introduced to improve loose coupling, discoverability, and evolvability. If the server can guide clients through links, it can change some URL structures or introduce new related actions without forcing every client to hardcode them immediately. In practice, many APIs do not achieve this fully, but the principle remains useful.
Real-Life Analogy
A website is the easiest analogy. When you visit an online shopping site, you do not type /products, /cart, /checkout, and /orders manually. You follow links, menus, buttons, and forms presented by the page. The current page tells you what you can do next.
HATEOAS brings that navigation style into API responses. A response for a product may include links to reviews, seller details, related products, add-to-cart action, or inventory status. A response for an order may include payment, cancellation, shipment, invoice, or return links depending on order status and user permission.
This makes the response more self-descriptive. The client receives not only the current resource data, but also the allowed next steps. That is the "engine of application state" idea: links guide the state transitions.
Traditional REST API vs HATEOAS API
In a traditional REST-like API, the client often knows endpoint templates in advance. It may construct URLs such as /users/101, /users/101/orders, /orders/500, and /products from configuration or code. This is common and practical, but it is not fully hypermedia-driven.
In a HATEOAS API, a client retrieves a resource and reads links from the response:
{
"id": 101,
"name": "John",
"links": [
{
"rel": "self",
"href": "/users/101"
},
{
"rel": "orders",
"href": "/users/101/orders"
},
{
"rel": "update",
"href": "/users/101",
"method": "PATCH"
},
{
"rel": "delete",
"href": "/users/101",
"method": "DELETE"
}
]
}
The client can discover what actions are available by reading the links. If the user is not allowed to delete the resource, the delete link may be omitted. If a resource is inactive, update links may be omitted. If a next page exists, a next link appears.
Components of a HATEOAS Link
A HATEOAS link usually contains a relationship name and a URI. The relationship, often written as rel, explains what the link means. The href gives the URI to follow. Some APIs also include the HTTP method, media type, title, or other metadata.
{
"rel": "orders",
"href": "/users/101/orders"
}
This means the related resource is orders, and the client can access it using the provided URI. A more detailed link may include method information:
{
"rel": "cancel",
"href": "/orders/500/cancellations",
"method": "POST",
"type": "application/json"
}
For testers, every field in a HATEOAS link can become a validation point. The relationship should be meaningful, the URI should be correct, the method should match the allowed action, and the media type should match the expected request or response format when included.
Common rel Values
Common relationship values include self, next, prev, first, last, create, update, delete, orders, products, customer, and payment. The value should describe the relationship or action clearly.
The self link points to the current resource. Pagination links such as next and prev help clients navigate list pages. Business links such as payment, invoice, shipment, or cancel guide clients to related workflows. Some rel values are standardized in broader web usage, while others are application-specific.
If an API uses custom rel values, they should be documented. Testers should not have to guess whether close, complete, submit, and finish mean the same thing. Consistent relationship naming is as important as consistent URI naming.
HATEOAS Flow
A HATEOAS flow begins with the client calling an entry point. The server returns a representation containing data and links. The client chooses one of the links based on user action or application logic. The next response then includes new data and new links appropriate for that state.
For example, a user response may include an orders link. The client follows that link to retrieve orders. An order response may include a payment link if payment is pending, a shipment link if shipment exists, or a cancel link if cancellation is still allowed. Once the order is shipped, the cancel link may disappear and a return link may appear.
This flow is state-aware. The links reflect what the client can do now, not every action that might ever exist. This is why HATEOAS can be useful for workflows with changing states and permissions.
Example: User Resource
A user resource response may include links to itself and related orders:
{
"id": 101,
"name": "John",
"links": [
{
"rel": "self",
"href": "/users/101"
},
{
"rel": "orders",
"href": "/users/101/orders"
}
]
}
The client now knows it can retrieve the user's orders by following the orders link. The client does not need to construct the orders URL from a hardcoded template. If the API later changes the exact route, a hypermedia-aware client can continue following the returned link.
Testing this response includes validating that the self link points to the current user, the orders link points to the correct user's orders, the rel values are correct, and the links are available only when the caller has permission.
Example: Order Resource
An order resource can show how HATEOAS represents relationships and state transitions:
{
"id": 500,
"amount": 250,
"status": "PENDING_PAYMENT",
"links": [
{
"rel": "self",
"href": "/orders/500"
},
{
"rel": "customer",
"href": "/customers/101"
},
{
"rel": "payment",
"href": "/payments/900"
},
{
"rel": "cancel",
"href": "/orders/500/cancellations",
"method": "POST"
}
]
}
This response says more than the order data. It says where the current order is, which customer owns it, where payment information lives, and whether cancellation is currently available. If the order is already delivered, the cancel link may be removed and a return link may appear instead.
For testers, this means link validation must be state-specific. It is not enough to check that a link array exists. The links must match the current resource status, business rules, and user permissions.
Pagination Example
Pagination is one of the most common practical uses of hypermedia links. A product list response may include next and previous links:
{
"products": [
{
"id": 1,
"name": "Laptop"
}
],
"links": [
{
"rel": "next",
"href": "/products?page=3"
},
{
"rel": "prev",
"href": "/products?page=1"
}
]
}
The client does not need to calculate the next page URL manually. It can follow the next link returned by the server. This is useful when pagination rules are complex, cursor-based, filtered, sorted, or subject to change.
Testers should verify that pagination links appear correctly. The first page should not usually have a previous link. The last page should not have a next link. Middle pages should have both where applicable. Query filters and sort options should be preserved in pagination links.
HATEOAS in REST Constraints
HATEOAS belongs to the uniform interface constraint of REST. The uniform interface makes REST APIs predictable by requiring resource identification, resource representations, self-descriptive messages, and hypermedia as the engine of application state. HATEOAS is the hypermedia part of that constraint.
This is why some architects say an API is not fully RESTful unless it uses HATEOAS. Many practical APIs use HTTP methods, resource URIs, JSON, and status codes but do not include hypermedia controls. They may be REST-like or pragmatic REST APIs rather than complete implementations of the original REST style.
For testers, the practical point is to follow the project contract. If the API claims HATEOAS support, validate links seriously. If the API does not claim HATEOAS support, do not invent requirements that the product never promised. However, understanding HATEOAS helps testers answer interview questions and evaluate advanced API designs.
Benefits of HATEOAS
HATEOAS promotes loose coupling because clients do not need to hardcode every URL. They can discover related actions dynamically. This can make clients more resilient to some API changes, especially when URL structures evolve but relationship meanings remain stable.
HATEOAS also improves discoverability. A response can show what related resources exist and what actions are currently allowed. This is useful for workflows where possible actions depend on resource status. A pending order may show payment and cancel links. A shipped order may show shipment and return links. A completed payment may show receipt links.
Another benefit is self-documenting behavior. Links communicate available next steps directly in the response. This does not replace API documentation, but it gives clients runtime guidance. It also supports permission-aware behavior: a regular user may not see an admin-only delete link.
Limitations of HATEOAS
HATEOAS has tradeoffs. It is more complex to design and implement than simple REST-like JSON APIs. Responses become larger because they include link metadata. Clients need additional logic to parse links, understand relationship values, choose actions, and handle missing links. Tooling and client libraries may not support hypermedia workflows naturally.
Many public APIs choose not to implement full HATEOAS because clients often prefer clear documentation and stable endpoint templates. Mobile apps and SPAs may hardcode routes for performance and simplicity. Backend service clients may use generated clients from OpenAPI specifications instead of dynamic link discovery.
This does not make HATEOAS useless. It means teams should use it where it adds real value: complex workflows, discoverable APIs, state-driven actions, and systems where loose coupling is a priority. For simple internal APIs, full HATEOAS may be unnecessary overhead.
HATEOAS vs Hyperlinks in Websites
HATEOAS is often compared to hyperlinks in websites because the idea is similar. In a website, the user sees links and buttons in HTML and chooses what to do next. In a HATEOAS API, the client receives links in JSON or XML and chooses what request to send next. HTML links are for human navigation through a browser. API links are for programmatic navigation by clients.
The important similarity is that the response tells the consumer what actions are available. A website may not show a checkout button if the cart is empty. A HATEOAS API may not include a checkout link if the cart has no items. A website may hide an admin link from normal users. A HATEOAS API may omit admin-only links for normal users.
Testing the two is conceptually similar. Verify that links appear when allowed, disappear when not allowed, point to the correct destination, and perform the expected action when followed.
Role-Based HATEOAS Links
Role-based links are one of the strongest practical uses of HATEOAS. The server can include different links based on the caller's permissions. An admin viewing a user resource may receive update and delete links. A regular user may receive only self and orders links. A guest may receive no private links at all.
For example, an admin response may include:
{
"rel": "delete",
"href": "/users/101",
"method": "DELETE"
}
A regular user response should not include that link if the user is not authorized to delete the resource. Testers should verify both visibility and enforcement. Hiding a link is helpful, but the server must also reject unauthorized direct requests to the delete URL. Link absence is not a security control by itself.
HATEOAS in API Testing
Testing HATEOAS means validating data and links together. Link presence checks confirm required links appear. Link accuracy checks confirm href values point to correct resources. Relationship checks confirm rel values are meaningful and consistent. Method checks confirm the correct HTTP method is supplied where the API includes method metadata. Navigation checks follow returned links and verify they work.
State-based testing is important. Available links should change as resource state changes. A draft invoice may include submit and edit links. A submitted invoice may include approve or reject links for authorized users. An approved invoice may include payment links. A paid invoice may include receipt links. Tests should verify links match those states.
Role-based testing is equally important. Admin, manager, regular user, guest, partner, and service accounts may receive different links. Tests should verify that links reflect permissions and that unauthorized direct calls are still blocked.
Broken Link Validation
HATEOAS links should not be broken. If a response includes a link, following it should return a documented response. A self link should retrieve the current resource. A related resource link should point to an existing or valid collection. An action link should perform the documented action when called with the required method and payload.
Broken link testing can be automated. A test can collect links from a response, follow selected safe links such as self, next, previous, or related read links, and verify status codes and response formats. For action links such as delete or payment, tests should be more careful because following them can change data. Use controlled test resources and explicit scenarios.
Broken links reduce trust in an API. If clients are expected to navigate by links, every link must be reliable. Link validation is therefore a core part of HATEOAS testing.
HATEOAS and API Evolution
One reason HATEOAS is attractive is API evolution. If clients follow links by relationship name instead of hardcoding every URL, the server has more flexibility to change route structures. For example, the orders link for a user could change from /users/101/orders to /customers/101/orders while clients following the orders rel continue to work.
This benefit requires disciplined clients and stable rel meanings. If clients ignore links and still hardcode URLs, HATEOAS does not provide much decoupling. If rel values change randomly, clients still break. HATEOAS works best when relationship names are treated as a stable contract.
Testers should include backward compatibility checks when HATEOAS links are part of a public API. Link rel values, required links, and state transitions should not change unexpectedly without versioning or migration guidance.
Designing a Clear HATEOAS Response Contract
A HATEOAS implementation becomes useful only when the response contract is clear. Adding a links array to a JSON response is not enough by itself. The team must define what each link means, when it should appear, who is allowed to see it, what method should be used, and what result the client should expect after following it. Without this agreement, hypermedia links become decorative metadata rather than reliable controls.
A strong contract normally starts with standard relationship names where possible. Values such as self, next, prev, first, and last are easy to understand because many developers already recognize them. Custom relationship names are also acceptable, but they should be consistent across the product. If one response uses orders, another uses orderList, and another uses customerOrders for the same idea, client code and test automation become harder to maintain.
The contract should also describe whether links are absolute or relative. Some APIs return complete URLs, such as https://api.example.com/orders/500. Others return relative paths, such as /orders/500. Both can work, but clients and tests must know how to resolve them. In multi-environment testing, relative links are often convenient because the same response works across QA, staging, and production domains. Absolute links can be clearer, but they must be validated carefully to avoid accidentally pointing from a test environment to production.
For action links, method information is important. A read link may be obvious because the client can use GET, but action links such as cancel, approve, retry, pay, resend, or archive are less obvious. If the API includes method metadata, testers can validate that the method matches the documented behavior. If the API does not include method metadata, the documentation must clearly explain how each action link is used.
A good response contract also explains conditional links. For example, an order may include a cancel link only while the order is pending. Once the order is shipped, the cancel link should disappear. A paid invoice may include a receipt link, while an unpaid invoice may include a payment link. These rules are not simple formatting details; they represent business behavior. When HATEOAS is used properly, link presence becomes a compact way to express the current state of the resource.
This is why testers should review HATEOAS contracts with both technical and business stakeholders. Developers can confirm URI patterns, methods, and media types. Product owners can confirm when actions should be available. Testers can convert these rules into meaningful assertions. The result is stronger than simply checking whether a links array exists, because the validation is tied to actual business rules and client behavior.
Practical Automation Coverage for HATEOAS APIs
Automating HATEOAS validation requires balance. A test suite should not blindly follow every link in every response, because that can create slow execution, unstable tests, duplicate coverage, and accidental data changes. At the same time, a HATEOAS API should not be tested as plain JSON data while ignoring the links that are central to its design. The practical approach is to classify links and decide the right depth of validation for each category.
Read-only links are usually the safest starting point. Links such as self, next, previous, first, last, customer, order, product, or address can often be followed with GET requests. Tests can verify that these links return successful responses, use the expected content type, and point to resources that match the original context. For example, if a user response includes an orders link, the returned order collection should belong to the same user. If a paginated list includes a next link, following that link should return the next page without losing filters or sorting.
Action links need more controlled automation. Links such as delete, cancel, approve, submit, refund, or retry may change application state. These tests should use dedicated test data that can be safely created and cleaned up. A cancel link should be tested on an order created specifically for that scenario, not on shared data used by other tests. A delete link should be tested only when the resource can be recreated or removed without affecting other scenarios.
Negative coverage is also important. If a user does not have permission to perform an action, the related link should normally be absent. However, the API must still reject a direct request to that action endpoint. A robust test checks both sides: the unauthorized user does not receive the action link, and a direct unauthorized call returns an appropriate error such as 401 or 403 depending on the authentication state. This prevents teams from treating hidden links as real security.
Schema validation can include link structures, but it should not be too rigid. It is reasonable to validate that each link has required fields such as rel and href. It is also reasonable to validate optional fields when the contract requires them. But tests should avoid freezing harmless ordering details unless ordering is part of the contract. Hypermedia responses may grow over time as new links are added, so validation should allow compatible additions while still catching broken or missing required links.
Automation should also include environment awareness. In lower environments, links should point to lower-environment domains or relative paths, not production. If an API gateway, reverse proxy, or load balancer rewrites URLs, tests should verify that generated links still resolve correctly from the consumer's perspective. Broken host names, wrong schemes, missing base paths, and mixed HTTP/HTTPS links are common defects in real systems.
Finally, reporting should make link failures easy to diagnose. A failure message should include the source endpoint, the rel value, the href value, the expected behavior, and the actual response. A message such as "link validation failed" is not enough. A better message says that the next link returned from /products?page=2 produced a 404, or that the cancel link was present for a shipped order where cancellation is not allowed. Clear diagnostics are especially important because HATEOAS failures often sit at the intersection of routing, permissions, resource state, and business rules.
Best Practices
Include meaningful links for related resources and valid next actions. Use consistent rel values across the API. Use standard rel values where appropriate and document custom rel values clearly. Include method and media type metadata when it helps clients understand how to use an action link.
Return only links the client is authorized to use, but do not rely on link visibility as the only security control. The server must still enforce authorization when a client calls an endpoint directly. Keep links accurate, stable, and useful. Avoid adding large numbers of irrelevant links that make responses noisy.
For pagination, preserve filters, sorting, and cursor values in next and previous links. For workflows, make links state-aware. For public APIs, document the hypermedia format, relationship meanings, and examples clearly.
Common Misconceptions
A common misconception is that every API called REST must implement full HATEOAS. In the original REST architectural model, HATEOAS is part of the uniform interface constraint. In practical industry usage, many APIs are called RESTful even when they do not implement HATEOAS. The right expectation depends on the project's architecture and contract.
Another misconception is that HATEOAS means HTML hyperlinks. HATEOAS can use links in JSON, XML, HAL, Siren, Collection+JSON, or another representation format. The client may be a program, not a person clicking a browser link.
A third misconception is that HATEOAS replaces HTTP methods. It does not. HTTP methods such as GET, POST, PUT, PATCH, and DELETE are still used. HATEOAS tells the client which URI and action are available; HTTP still defines how the request is made.
Interview-Ready Explanation
HATEOAS stands for Hypermedia as the Engine of Application State. It is a principle of the REST uniform interface constraint where an API includes hypermedia links in its responses so clients can dynamically discover related resources and available actions instead of hardcoding every endpoint URL.
A HATEOAS response may include links such as self, next, prev, orders, update, delete, payment, or cancel. Each link commonly has a rel value that describes the relationship and an href value that gives the URI. Some APIs also include method and media type information. Clients move through the API by following these links, similar to how users navigate websites through hyperlinks.
In API testing, HATEOAS is validated by checking link presence, link accuracy, rel consistency, link navigation, pagination links, state-based links, role-based links, and broken links. HATEOAS improves loose coupling, discoverability, and API evolution, although many real-world REST APIs do not fully implement it.
Key Takeaway
HATEOAS is the hypermedia-driven part of REST. It allows API responses to guide clients by including links to related resources and valid next actions. Instead of relying entirely on hardcoded URLs, clients can discover what to do from the response itself.
For API testers, the practical rule is to treat links as part of the response contract. Validate that links exist when required, disappear when not allowed, point to correct resources, preserve pagination and filters, reflect user permissions, and work when followed. Strong HATEOAS testing improves confidence in discoverability, workflow behavior, and RESTful API design.