Home / Blog / JavaScript & TypeScript

API & webhooks

JavaScript REST API Call: Check Status, Data, and Cancellation

Make a browser REST request with fetch, distinguish HTTP and parsing errors, validate the expected note shape, and cancel an operation deliberately.

Start with the endpoint's expected result

A JavaScript REST call needs more than a URL and response.json. Decide which HTTP statuses represent success, whether a body is expected and which fields the caller requires. That lets the client distinguish a missing note, invalid JSON and a valid JSON object that does not match the application's contract.

The following example expects a successful JSON object with a string title. It is deliberately scoped to that endpoint shape. An API returning a collection, binary data or an empty success response needs a different reader rather than a hidden fallback that pretends every response is the same kind of note.

Keep the request function independent of the interface

async function getNote(url, signal, fetcher = fetch) {
  const response = await fetcher(url, {
    headers: {Accept: "application/json"},
    signal
  });
  if (!response.ok) {
    await response.body?.cancel();
    throw new Error(`Note request failed: HTTP ${response.status}`);
  }
  const note = await response.json();
  if (!note || typeof note !== "object" || Array.isArray(note)
      || typeof note.title !== "string") {
    throw new Error("Expected a note object with a title string.");
  }
  return note;
}

The optional signal lets the caller cancel this operation through an AbortController. The optional fetcher makes deterministic tests possible without contacting an external service. Ordinary callers can omit the third argument and use the browser's native fetch implementation.

A successful HTTP response is checked before parsing. A readable 404 therefore produces an error containing the HTTP status rather than a misleading message about an unexpected character in an HTML error page. The example cancels the unread error body; it does not publish private server diagnostics.

Handle asynchronous completion at the call site

Call getNote from an async function and await its promise inside try and catch. Returning a promise from a function does not make its result immediately available to the next line of synchronous code. Avoid writing a variable in a callback and assuming it has already been populated outside that callback.

Keep loading state in the caller that owns the interface. That caller knows whether the user navigated away, changed the selected note or cancelled the request. A reusable transport helper should not update an unrelated page element simply because a response arrived.

Classify failures without flattening them

The Fetch guide explains that HTTP error statuses do not automatically reject the fetch promise. Network failures and cancellation can reject before the code reaches the status check. A JSON parsing failure happens later, after a readable response is available.

Present a useful message for the stage that failed. Do not label every failure as an expired login, and do not suppress every exception by returning an empty object. A caller that receives an empty object may continue rendering a success state even though the request never produced a valid note.

Account for the browser's origin policy

A cross-origin API must permit the browser request through its server-side CORS policy. Adding Access-Control-Allow-Origin to the client request does not grant that permission. Using no-cors is also not a way to obtain a normal readable JSON response from an otherwise blocked service.

If authentication uses cookies, follow the service's credential and cross-site request protections. If it uses a token, attach the documented header without embedding privileged server secrets in public JavaScript. Authentication and CORS are related integration concerns, but fixing one does not automatically fix the other.

Test the contract and the cancellation path

Test a normal note, an empty title that the contract intentionally allows, an HTTP error, malformed JSON and a wrongly shaped value such as an array. Assert that errors remain errors instead of becoming successful empty data. Test cancellation against a delayed controlled response as well.

The REST API Testing Tool can inspect an authorized endpoint's status, body and browser-visible headers before you wire it into the interface. Use a local fixture for repeatable tests and check the real application's loading, failure and cancellation states separately.

Finally, verify the exact deployed origin and endpoint. A development proxy can make a local call work while production uses a different path or CORS policy. Save the intended request details without retaining credentials so that this difference can be investigated.