
Fantastic new APIs are coming to Angular. Two years ago, we proposed making Angular a reactive web framework powered by signals. Since then, the team has shipped a number of signal-based features in the framework: reactive primitives like signal
& computed
, reactive input
s including model
, signal queries, bidirectional RxJS conversion utilities, and migration tooling.
Angular 即将推出精彩的新 API。两年前,我们提议将 Angular 打造成一个由信号驱动的响应式 Web 框架。从那时起,团队就在框架中推出了许多基于信号的功能:响应式原语(如signal
和computed
、响应式input
(包括model
、信号查询、双向 RxJS 转换实用程序和迁移工具。
We have a solid foundation for reactivity in Angular. Now, we’re ready to begin the next phase of the reactivity journey: the world of asynchronous state. In v19 we shipped the experimental resource()
API for developers to try out in advance of the dedicated RFC.
我们在 Angular 中为响应式打下了坚实的基础。现在,我们已准备好开始响应式旅程的下一阶段:异步状态的世界。在 v19 中,我们发布了实验性的resource()
API,供开发人员在专用RFC之前试用。
The resource API makes it possible to expose results of asynchronous operations as signals. For most applications, developers make HTTP requests for the data their applications need. We recognize this and have built a new API to help facilitate this primary use case — introducing httpResource
🎉.
资源 API 可以将异步操作的结果公开为信号。对于大多数应用程序,开发人员会发出 HTTP 请求以获取其应用程序所需的数据。我们认识到这一点,并构建了一个新的 API 来帮助促进这一主要用例 — 引入httpResource
🎉。
httpResource
is built on top of the resource
primitive and uses HttpClient
as loader. It acts as a frontend for @angular/common/http
. It makes HTTP requests through the Angular HTTP stack, including interceptors. As the underlying stack remains the same, testing will rely on the same tools.httpResource
建立在resource
原语之上,并使用HttpClient
作为加载器。它充当@angular/common/http
的前端。它通过 Angular HTTP 堆栈(包括拦截器)发出 HTTP 请求。由于底层堆栈保持不变,因此测试将依赖相同的工具。
Here we are defining an httpResource with currentUserId
as a reactive parameter.
这里我们定义一个 httpResource,以currentUserId
作为反应参数。
currentUserId = getCurrentUserId(); // returns a signal
user = httpResource(() => `/api/user/${currentUserId()}`); // A reactive function as argument
By default, an httpResource
will perform a GET request and return an unknown typed JSON response.
默认情况下, httpResource
将执行 GET 请求并返回未知类型的 JSON 响应。
It is important to note that httpResource
differs from the HttpClient
as it initiates the request eagerly (unlike the HttpClient
Observable-based requests which must be subscribed).
值得注意的是, httpResource
与HttpClient
不同,因为它会急切地发起请求(与必须订阅的基于HttpClient
Observable 的请求不同)。
Like resource
, it configures a reactive request. If any of the source signals in the request computation change, a new HTTP request will be made.
和resource
一样,它配置了一个反应式请求。如果请求计算中的任何源信号发生变化,就会发出新的 HTTP 请求。
For more advanced requests, it is possible to define a request object similar to HttpClient
‘s request.
对于更高级的请求,可以定义类似于HttpClient
的请求对象。
user = httpResource(() => ({
url: `/api/user/${currentUserId()}`,
method: 'GET',
headers: {
'X-Special': 'true',
},
params: {
'fast': 'yes',
},
reportProgress: true,
withCredentials: true,
transferCache: true,
}));
While the resource pattern is meant only for retrieving asynchronous data, httpResource
will allow any request method (like POST in the previous example). This still doesn’t mean that you should be using httpResource to change data on the server. For instance, if you need to submit form data, use the HttpClient
methods.
虽然资源模式仅用于检索异步数据,但httpResource
将允许任何请求方法(如上例中的 POST)。但这并不意味着您应该使用 httpResource 来更改服务器上的数据。例如,如果您需要提交表单数据,请使用HttpClient
方法。
An httpResource
will return and parse the response as JSON but it is possible to use it for other return types.httpResource
将返回并解析响应作为 JSON,但也可以将其用于其他返回类型。
The API has multiple dedicated methods available for other response types:
该 API 有多个专用方法可用于其他响应类型:
httpResource.text(() => ({ … })); // returns a text in value()
httpResource.blob(() => ({ … })); // returns a Blob object in value()
httpResource.arrayBuffer(() => ({ … })); // returns an ArrayBuffer in value()
An httpResource , similar to other `resource`, exposes several signals:
与其他“资源”类似,httpResource 公开了几个信号:
value()
— which contains the result of the http request (when successful) and is programmatically overwritablevalue()
— 包含 http 请求的结果(成功时),并且可以通过编程覆盖status()
— with the status of the resource (idle, loading, error etc)status()
— 资源的状态(空闲、加载、错误等)error()
— with the request error / parsing errorerror()
— 请求错误/解析错误isLoading()
— which is true while the request is pendingisLoading()
— 请求处于待处理状态时为 trueIt also includes dedicated signals for metadata about the response:
它还包括有关响应的元数据的专用信号:
headers()
— with the response’s headersheaders()
— 带有响应的标头statusCode()
— with the response’s status codestatusCode()
— 响应的状态代码progress()
— with the progress of the request (if required in the request object)progress()
— 请求的进度(如果请求对象需要)These new signals streamline the writing of requests by exposing this useful information without requiring a specific argument like for the HttpClient
to request the HttpResponse
.
这些新的信号通过公开有用信息简化了请求的编写,而不需要像HttpClient
请求HttpResponse
那样使用特定参数。
When performing http requests we often want to ensure that the data we receive conforms the shape that we expect. This is commonly known as schema validation.
当执行 http 请求时,我们经常希望确保收到的数据符合我们期望的形式。这通常称为模式验证。
In the JavaScript ecosystem we often reach out for battle-tested libraries like Zod or Valibot for schema validation. The httpResource
offers direct integration for those libraries by using the parse
parameter. The returned type of this parse
function will provide the type to the resource itself, ensuring type safety alongside the schema validation.
在 JavaScript 生态系统中httpResource
我们经常使用Zod或Valibot等久经考验的库来进行架构验证。httpResource 通过使用parse
参数为这些库提供直接集成。此parse
函数的返回类型将为资源本身提供类型,从而确保架构验证的同时确保类型安全。
The following example uses Zod to parse and validate the response from the StarWars API. The resource is then typed the same as the output type of the Zod’s parsing.
以下示例使用 Zod 解析并验证来自StarWars API的响应。然后,资源的类型与 Zod 解析的输出类型相同。
export class AppComponent {
id = signal(1);
swPersonResource = httpResource(
() => `https://swapi.dev/api/people/${this.id()}`,
{ parse: starWarsPersonSchema.parse }
);
}
const starWarsPersonSchema = z.object({
name: z.string(),
height: z.number({ coerce: true }),
edited: z.string().datetime(),
films: z.array(z.string()),
});
Demo on Stackblitz Stackblitz 上的演示
The httpResource
is available as a part of the Angular v19.2 release. This is an experimental API and is not ready for production because the shape of this API can still change before it is promoted to stable. With that in mind, we would love for you to try out the API and let us know what you think. You can learn more about this API, resource and more in the RFC on GitHub.httpResource
是 Angular v19.2 版本的一部分。这是一个实验性的 API ,尚未准备好投入生产,因为此 API 的形式在升级为稳定版本之前仍可能发生变化。考虑到这一点,我们希望您尝试该 API 并让我们知道您的想法。您可以在 GitHub 上的 RFC 中了解有关此 API、资源等的更多信息。
Thank you for being a part of the Angular community and we look forward to continuing the reactivity journey together. Happy coding!
感谢您成为 Angular 社区的一员,我们期待着继续一起踏上响应式旅程。祝您编码愉快!
原文地址:https://blog.angular.dev/seamless-data-fetching-with-httpresource-71ba7c4169b9