Home / Blog / API & webhooks

API & webhooks

REST API GET Example: Read and Validate One Resource

Build a resource GET request, encode the identifier, check HTTP status and response shape, and distinguish a missing resource from an empty collection.

Start with a resource and its expected representation

A REST-style resource GET asks the service for a representation at a particular URL. For a fictional notes API, GET /notes/7 might return one note object. Its contract should specify the identifier format, authentication requirements and representation, rather than leaving the client to guess from one successful sample.

The GET method reference describes a read operation. Do not design the sample GET as a command that deletes, charges or creates something simply because calling it in a browser is convenient.

Encode the identifier and validate the response

async function readNote(baseUrl, id, fetcher = fetch) {
  if (typeof id !== "string" || !/^[A-Za-z0-9_-]+$/.test(id)) {
    throw new Error("Use a nonempty note identifier.");
  }
  const url = new URL("notes/" + encodeURIComponent(id), baseUrl);
  const response = await fetcher(url, {
    method: "GET", headers: {Accept: "application/json"}
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const note = await response.json();
  if (!note || Array.isArray(note) || note.id !== id ||
      typeof note.title !== "string") {
    throw new Error("Unexpected note representation.");
  }
  return note;
}

This example accepts a deliberately narrow identifier alphabet. It rejects an empty identifier and path-like values before making a request. A service with a different identifier grammar needs a corresponding validator; do not remove checks solely to make an unrelated endpoint fit the example.

Give baseUrl a trailing slash when it names a base directory, such as https://api.example.com/v1/. The relative path notes/7 then resolves under /v1/. Without that slash, URL resolution can replace the final base path segment, which may send the request to an unintended route.

Do not equate valid JSON with the right object

The helper checks that the returned identifier matches the requested string and that title is text. It permits an empty title because this illustrative response contract does not prohibit it. It rejects a list, null or an object for another identifier.

These checks are intentionally small. They do not validate every possible note field or authorize the caller. If the endpoint publishes a formal response schema, apply the agreed schema and version, including the intended treatment of unknown fields.

When several reads can overlap, the surrounding interface also needs request ownership. A slow response for note 7 must not overwrite a newer selection of note 9. This helper returns one verified object but does not decide which request is current. Use cancellation or an accepted-request identifier in the caller, and test the older response arriving last.

Separate a missing resource from an empty search

A request for one nonexistent note can return 404 under the service's policy. A request for a note collection whose filter matches nothing can instead return a successful empty items array. The two cases answer different questions and should not be collapsed into the same undocumented sentinel value.

For example, /notes/7 asks for a particular resource, while /notes?q=mountain asks for a filtered collection. Decide how each result appears in the interface. An empty search message should not hide an authentication error or a malformed response.

Test the browser and service boundaries

A command-line request and a browser request do not share identical constraints. A cross-origin browser call needs the service's sharing policy, and a protected resource needs the documented credentials. The Fetch guide explains these client-side considerations.

Keep real tokens out of the sample URL and saved test output. The helper above deliberately has no authentication option. Add the service's intended mechanism in a controlled application layer, rather than embedding a secret in an article or a shared debugging link.

Verify two resources and the failure branches

Use two local fixture notes with different identifiers and titles. Assert that each call produces its matching result, and reject a response that returns the first note for the second request. Include a 404, malformed JSON, an array and a missing title.

The REST API Testing Tool can display an authorized request's readable status, headers and body. It does not apply this helper's note-specific shape checks. Compare the returned object with the actual endpoint contract before using it in your application.