Angular and the Resource API

Published on Nov 05, 2025

Introduction

Signals have been a great introduction to Angular, perhaps one of the best received additions for many years. The reactivity that they provide for your API, and the simplicity with which you can use them, is the main reason for that. However, initially the use case where you might make an API call but then place the results in a signal were somewhat clunky and unclear. However, the experimental Resource API aims to fix these inconveniences.

The Main Problem

Experienced Angular developers will know this, but for those that may be new to the community, here's a brief overview of how Angular apps make HTTP calls. Generally speaking, you will inject the HTTP Client from the framework. This service makes HTTP calls for you, using RxJS observables behind the scenes. The observable needs to be subscribed to for the call to be made, and the data comes back and can be fed through an RxJS pipeline to manipulate the data as needed before being used in your component.

Now, if you wanted to use the data from this HTTP call in a signal rather than an observable, you would need to manually do that. You might extract the data from the observable and update the signal, or use the toSignal method from @angular/core/rxjs-interop. This isn't a very clean method of getting the data in signals, however, and may cause some issues for you down the road, in either functionality or maintainability. The good thing is that Angular is working on a new service, called the Resource API, that should handle most of this for us.

Angular Resource

The Resource API is still experiemental as of the time of this blog post, so some of the things mentioned here may have been updated or changed as it's worked on. However, its purpose is to take an asynchronous dependency (some data from an API call, for example) and manage it through signals. Let's look at using httpResource, which will feel very familiar since it's based on the HttpClient.

httpResource

For our httpResource example, let's look at a simple component that needs to get data from an API. All that is required for using the httpResource is a function that returns a URL, which will be used to request the data.

import { httpResource } from '@angular/common/http';
export class MyComponent {
	public pikachu = httpResource<Pokemon>(() => 'https://pokeapi.co/api/v2/pokemon/pikachu')
}

In this example, we use httpResource to make the call to the Pokemon API to retrieve the data about Pikachu. The API is called and the result is automatically inserted into the signal. The resource (pikachu) also has some helper signals on it as well, like isLoading, error, and status, in addition to the value signal where the data resides. This makes it really easy to update the UI based on the status of the API call with the pikachu signal.

Now, this is nice and helpful, but many times we have some data that the API relies on to get the correct data from the API. The great thing is that httpResource will automatically make another call if a signal that it relies on is updated. Let's look at our component again:

import { httpResource } from '@angular/common/http';
import { signal } from '@angular/core';

export class MyComponent {
	public pokemonSearchTerm = signal('pikachu')
	public pokemon = httpResource<Pokemon>(() => `https://pokeapi.co/api/v2/pokemon/${this.pokemonSearchTerm()}`)
}

In this case, we have a new signal, pokemonSearchTerm, which is initialized with 'pikachu'. The API call is made with that value, and when the search term is updated, for example to 'bulbasaur', the API will be called again with the new value. Once again, the isLoading signal will return true and your UI can reactively be updated.

rxResource

rxResource is another helpful piece of the Angular Resource story. Many people out there have large applications that already have many data access services set up for getting data from their API. As such, it might make sense to not rewrite all the data access code. That's where rxResource shines. This resource can take an RxJS-based call and convert it to a signal for you. Here's another example of our initial component:

import { rxResource } from '@angular/core/rxjs-interop';
export class MyComponent {
	private pokeApiService = inject(PokeApiService);

	public pikachu = rxResource({
		stream: () => {
			return this.pokeApiService.getPikachu()
		}
	})
}

In this example, we take an RxJS-based service that gets Pikachu's information from the API, and which is then converted to a signal for us. All we need to do is return an RxJS observable from the stream option of rxResource. However, it's not likely that we'll call an API for just one specific item like this. Let's update the example

import { rxResource } from '@angular/core/rxjs-interop';
export class MyComponent {
	public pokemonSearchTerm = signal('')
	private pokeApiService = inject(PokeApiService);

	public pikachu = rxResource({
		params: this.pokemonSearchTerm,
		stream: (params) => {
			if (!params.params) {
				return of(undefined);
			}
			return this.pokeApiService.searchPokemon(params.params)
		}
	})
}

This is very similar to the last example, but we provide a params attribute to the options passed in to the rxResource, and assign it to our pokemonSearchTerm signal. If there is no value in the params, then we just return an observable with undefined as the value (which, this just so happens to be the default value of an rxResource). Otherwise, we take the search term and call the API. Just like with the httpResource, we are given signals on the rxResource for isLoading and value.

Quick Tips

There are a few things to note about the Resource API before we finish up.

  • The first is that this API is only for retrieving data, not mutating it. That means only use it for GET requests, not POST or PUT or DELETE requests.
  • Another thing to note is that you can use a plain resource (instead of httpResource or rxResource) if you want to use the native fetch API instead of the HttpClient.
  • httpResource has a parse option that allows you to transform data and provide data validation if needed when the data comes back from the API and before it's stored in your signal.
  • Last but not least, remember that this is experimental and can change at any time.

Conclusion

Signals continue to grow in the Angular community, and become more and more prevalent. As such, tools like this will be provided by both the Angular team and the community to make the move to signals easier and more intuitive. Keep an eye on the Resource API as it moves out of experimental status and into stable.