[Complete] Resource RFC 2: APIs #60121
Replies: 50 comments 190 replies
-
question 3: I would definitely rename |
Beta Was this translation helpful? Give feedback.
-
Sorry for not responding to any question of the RFC, but I feel that some questions are missing in the discussion. current valuewhat about the behavior of the resource regarding the current value when reloading, either imperatively, or because of a request signal change. The RFC says:
This looks wrong to me. I think that depending on the UI needs, either we want to switch to a loading spinner every time there is a reload, or we want to keep the current value (and maybe display a loading spinner in addition to the value) every time there is a reload. I find it weird to force the loss of the current value when loading, which makes it impossible to keep the current value displayed. Cancellation / unsubscriptionThis is actually related to Question 7. TestingThe common and best practice today, when not using resources, is to delegate to services to make HTTP requests. This makes it very convenient when testing the component because it's easy to mock/fake the service and make it return an observable created with |
Beta Was this translation helpful? Give feedback.
-
Why is this the case? As an educator and mentor of many junior engineers, it's much easier to help enforce the new standards of Signals (especially in a Zoneless app) that most reactive values are marked as signals for quick grok-ability. |
Beta Was this translation helpful? Give feedback.
-
I may be in the minority here, but I'd actually much rather not use a TypeScript enum here and rather just use a TS union of string constants |
Beta Was this translation helpful? Give feedback.
-
Not only do I find this distinction useful, it's incredibly important for what, IMO, is the correct loading pattern of having cached results from the previous call still display in the UI while displaying a mini loading spinner indicating the refetching behavior. All apps should have:
|
Beta Was this translation helpful? Give feedback.
-
Does the Ultimately I like the idea of not having to use TypeScript generics to cast type-safe values at all. |
Beta Was this translation helpful? Give feedback.
-
One thing that I also find quite strange in the API is the |
Beta Was this translation helpful? Give feedback.
-
My feedback comes after having used resources in both SolidJS and now Angular. Regarding the questions: Question 1: (enum vs. string literal) Question 2: (usefulness of Reloading status) Question 3: (name of resource options) Question 4: (streaming API) Question 5: (more uncommonly requested types) Question 6: (type-safety in httpResource) There is always much more boiler plate to write to extract errors and there just isn't a good reason for it. Question 7: Now my two cents regarding resources:
In my limited time, I have worked on a function called listResource that I quite like (it doesn't have type narrowing, cause I'm bad at TS type juggling, but the idea is as follows). This is how it is used: combinedFilters = computed(() => ({
startDate: this.startDate(),
endDate: this.endDate(),
sortBy: this.sortBy(),
}));
myList = listResource({
filterSource: this.combinedFilters,
fetcher: async (filters, pagination, notifyEndReached) => {
const newRows = await fetchMore(filters, pagination);
notifyEndReached(newRows.length < 50);
return newRows;
},
// Optional options here (this is actually the default behaviour):
initPaginationValue: 0,
getNextPagination: (currentItemList, lastPage) => {
return lastPage + 1;
},
});
// Some readonly signals:
myList.data();
myList.isLoading();
myList.isLoadingMore();
myList.isError();
myList.isEndReached();
// Some methods to reset and load more data:
myList.reset();
myList.loadMore(); Type definitions for those who care: type ResourceListState = "loading" | "loading-more" | "loaded" | "end-reached" | "error";
interface ListResource<Type, FilterType, PaginationType> {
readonly state: Signal<ResourceListState>;
readonly hasData: Signal<boolean>;
readonly data: Signal<Type[] | null>;
readonly isLoading: Signal<boolean>;
readonly isLoadingMore: Signal<boolean>;
readonly isError: Signal<boolean>;
readonly isEndReached: Signal<boolean>;
loadMore(): boolean;
reset(): void;
mutateList(mutationOperation?: (list: Type[]) => void): void;
}
type ResourceListFetcher<Type, FilterType, PaginationType> = (
filters: FilterType,
pagination: PaginationType,
notifyEndReached: (endReached: boolean) => void,
abortSignal: AbortSignal,
) => Promise<Type[]> | Observable<Type[]>;
type ResourceListOptions<Type, FilterType, PaginationType> = {
filterSource: Signal<FilterType>,
fetcher: ResourceListFetcher<Type, FilterType, PaginationType>,
initPaginationValue: PaginationType,
getNextPagination?: (currentItems: Type[], previousPagination: number) => number,
injector?: Injector;
};
function listResource<Type, FilterType, PaginationType>(
options: ResourceListOptions<Type, FilterType, PaginationType>,
): ListResource<Type, FilterType, PaginationType>; Something like this should exist natively, because it's easy to get this wrong, between cancelation of requests when filters change, etc. Maybe the most controversial take I have about resources (that is because my own resource implementation did this, so I may be biased): Edit: I had mentioned this in the original resource-PR, but I would also like it to be possible to access |
Beta Was this translation helpful? Give feedback.
-
Question 5: |
Beta Was this translation helpful? Give feedback.
-
Probably a dumb request, but can there be an I know EDIT: Regarding RFC question 2, my vote goes to a string union type. |
Beta Was this translation helpful? Give feedback.
-
Apologies if the expectation is to only answer the prompts. I'm primarily concerned with the decision to discourage mutations in It's name implies that it's designed to interact with HTTP resources. The clearest definition of an HTTP resource is:
As an example, a resource could be Suggestions: if |
Beta Was this translation helpful? Give feedback.
-
When I introduce the userId: Signal<string> = ...; // e.g. input
user = httpResource(`/api/user/${this.userId()}`); instead of doing userId: Signal<string> = ...; // e.g. input
user = httpResource(() => `/api/user/${this.userId()}`); Are the overloads with static values ( Doing it wrong does work sometimes, but of course doesn't react to changes. And if you have a required input signal, you get the error, that a value is not provided yet (of course). And that leads the junior devs on the wrong path, because then they start to setup the In my application I have only a handful of data requests, that don't use any filter parameters (from query etc.). Almost every fetch needs some parameter. So I won't miss the static overloads. |
Beta Was this translation helpful? Give feedback.
-
I would like to see string literals as status values (like |
Beta Was this translation helpful? Give feedback.
-
Yes, distinguishing between those two states is valuable. |
Beta Was this translation helpful? Give feedback.
-
I prefer And naming the function I would prefer (like
Regarding That would open up to future overloads with something like |
Beta Was this translation helpful? Give feedback.
-
I've been playing around with |
Beta Was this translation helpful? Give feedback.
-
I would love to see a pattern like in AngularQuery where you can create a custom injector and inject your data when needed but without refetching the backend if the data is fresh. export const injectTodos = () => {
assertInInjectionContext(injectTodos);
const apiUrl = injectApiUrl();
const dataId = injectRouteQueryParams<string>('dataId');
const TODO_API = 'todo';
return httpResource(
() => `${apiUrl}/${TODO_API}?dataId=${dataId()}`,
);
};
@Component({
selector: 'todos-list',
template: ` <div>{{ todos.value() }}</div>`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TestComponent {
// I expect to have only one request
public todos = injectTodos();
}
@Component({
selector: 'todos-list',
imports: [TestComponent],
template: `
<todos-list/>
<todos-list/>
`
})
export class ParentComponent {
} |
Beta Was this translation helpful? Give feedback.
-
About Q2: |
Beta Was this translation helpful? Give feedback.
-
In all honesty, I'd say the best approach would be to have both a status and a
I tend to agree that |
Beta Was this translation helpful? Give feedback.
-
Question 3: what about searchTerm = signal<string>(''); // used as an [(ngModel)] for an input
data = rxResource({
loader: () => this.myService.find(this.searchTerm()),
request: this.searchTerm
}); VS. searchTerm = signal<string>(''); // used as an [(ngModel)] for an input
data = rxResource({
loader: () => this.myService.find(this.searchTerm()),
trigger: this.searchTerm
}); |
Beta Was this translation helpful? Give feedback.
-
Not sure if anyone has mentioned this here regarding the statuses topic - but these statuses are a great use case (in my opinion) for an as const POJO (Plain Old JavaScript Object) that you can then also create a matching type for that exposes some additional type-safety, like an enum. That way you get that same enum behavior but without the enum itself (which has been proven many times by many people to be a part of the TS language that is not ideal both in its construction and runtime behavior behind the scenes). Check out @mattpocock's video here if you haven't seen it already: https://www.youtube.com/watch?v=jjMbPt_H3RQ |
Beta Was this translation helpful? Give feedback.
-
Would love to see a clear and simple way to defer requests based on some reactive trigger. I have a set of Resources defined in a component with multiple |
Beta Was this translation helpful? Give feedback.
-
Kinda late to the party😅 I haven't been able to go through all the comments here (a bit overwhelming I must say), so pardon me if any of my points have already been discussed and answered. My first reaction is actually more about feature parity with the existing RxJS-based HTTP client, which isn't mentioned much in the RFC. I guess it all boils down to whether there will be declarative equivalents (in the form of some configuration parameters) of the following RxJS operators in this new resource API:
You know, the usual stuff. They are pretty handy, so I'd rather we still have them with the new API. Q1: Maybe template literals? That'd be cleaner in my book. Or expose all the available states via signal getters/methods, like Q2: Is it really necessary to empty the values when the resource is loading due to a reactive signal update? I seriously doubt it. For example, when I update the search box for a list of to-do items, why should the to-do list be emptied while the backend search and data fetching are happening? Q3: Q4: At first glance, yes. Q5: N/A Q6: Appreciate the additional parser option. Would it be limited to synchronous parsers? Many validation/schema libraries allow async validation on their own. Would that cause (timing/scheduling) problems? And what would happen when the parsing/validation fails? Can we specify error handlers for that? Q7: N/A |
Beta Was this translation helpful? Give feedback.
-
i would say i love the idea of the httpResource but for consistency keep the JSON option as other options like text / blob .... this.#router.navigate([], {
queryParams: params,
queryParamsHandling: 'replace',
}); to keep the URL sync with the data filtered by the user export function getStablePaginationHttpResource<T>(
url: string,
paramsSignal: IPaginatedRequestSignal,
syncWithUrl: boolean
): TStableResource<IPaginatedResponse<T>> {
const queryParamsService = inject(QueryParamsUtilityClass, {
optional: true,
});
const resource = httpResource<IPaginatedResponse<T>>(
() => {
const params = getPaginationResourceRequest(paramsSignal);
if (syncWithUrl) queryParamsService?.updateQueryParams(params);
return {
url: url,
params: { ...params },
};
},
{ defaultValue: PAGINATION_RESPONSE_DEFAULT }
);
const stableValue = linkedSignal<
HttpResourceRef<IPaginatedResponse<T>>,
IPaginatedResponse<T>
>({
source: () => resource,
computation: (value, prevValue) =>
value.isLoading() && prevValue ? prevValue.value : value.value(),
});
return {
resource: resource,
stableValue: stableValue,
};
}
const PAGINATION_RESPONSE_DEFAULT: IPaginatedResponse<never> = {
current_page: 1,
data: [],
per_page: 10,
total: 0,
}; |
Beta Was this translation helpful? Give feedback.
-
(Apologies for not following the format of the RFC questions) Firstly, I fully support a) moving to a string union to represent the I'd like to discuss the modelling of streams using a (potentially) better In particular: I prefer to think of streams as being connected or disconnected (or in connecting or error states). I find that you often want to explicitly manage this connection (as touched on in previous comments in this RFC, when folks have talked about adding an (Aside: for token-based auth, you want to treat it like a stream because a refresh token call may fail if e.g. a user is banned). Below are a couple of examples of how I'm modelling state for two different NgRx SignalStores that use RxJS streams under the hood: type DisconnectedState = {
status: 'disconnected';
user: null;
error: null;
};
type ConnectingState = {
status: 'connecting';
user: null;
error: null;
};
type ConnectedState = {
status: 'connected';
user: User | null;
error: null;
};
type ErrorState = {
status: 'error';
user: null;
error: string;
};
type AuthState = DisconnectedState | ConnectingState | ConnectedState | ErrorState;
const initialState: AuthState = {
status: 'disconnected',
user: null,
error: null,
}; type DisconnectedState = {
status: 'disconnected';
categories: [];
error: null;
};
type ConnectingState = {
status: 'connecting';
categories: [];
error: null;
};
type ConnectedState = {
status: 'connected';
categories: string[];
error: null;
};
type ErrorState = {
status: 'error';
categories: [];
error: string;
};
type ConfigState = DisconnectedState | ConnectingState | ConnectedState | ErrorState;
const initialState: ConfigState = {
status: 'disconnected',
categories: [],
error: null,
}; (I give two very similar examples just to show how two different use cases can be modelled in the same fashion). Then, the relevant stores expose a For reference, here are the two store implementations in full:
I'm not yet sure how my thoughts above could be incorporated into this proposal, or how I would use the new resource-based APIs to replace this, but I'll share some off-the-cuff thoughts:
Overall, I think that trying to fit stream-based resources into the same model as the other resources may be detrimental, and seems to move us further away from the semantics of RxJS and stream-based processing. |
Beta Was this translation helpful? Give feedback.
-
Does it make sense that
I guess designing it like that could have the advantage that each dedicate type does not have to deal with According to the docs
Does this mean that I guess the approach using a union type based on a discriminator could have disadvantages too, or at least I did not think it through in detail yet, but I just wanted to share the thought and concerns about API’s including If the resource is in a state of error I would assume that a value for this error is available, hence that it can’t be undefined. The same is true for being in a success state. I would assume that a value is available, which again can’t be undefined, hence adheres to the value retuned by the loader. This semantics should be reflected in the type system as well. If I know that the state is “resolved”, then in the best case I don’t want to be forced checking if a value is available. I hope this makes sense. I did not fiddle around with Resources in detail yet, so don’t blame me if this concerns are already resolved. I just wanted to share the thought. The work regarding this topic is highly appreciated. Thanks. 🙏 |
Beta Was this translation helpful? Give feedback.
-
From my experimentation, resource clearing the value when request change IS logically correct but is really NOT ideal for UX Imagine following example
Current "workround" is to use products = rxResource({
defaultValue: [],
request: this.debouncedQuery,
loader: ({ request }) => this.#productService.find(request),
});
// workaround to NOT lose items when reloading to prevent jumpy UX ( UX concern)
productsList = linkedSignal<Product[], Product[]>({ // needs explicit generic type
source: () => this.products.value(),
computation: (source, previous) =>
this.products.status() === ResourceStatus.Loading && previous
? previous.source
: source,
}); it's not an IDE issue, compiler complains about it as well Desired behavior OrderApp.-.Google.Chrome.2025-03-18.10-47-43.mp4 |
Beta Was this translation helpful? Give feedback.
-
Q1: I personally won't use enums (unless they are implemented natively in JavaScript directly). If it is a const object instead, why not. But as you first need to reference it in the class first, right now, I would prefer the union type Q2: As far as I've been using it, I never had any use case where the reloading state was relevant. I would always expect the loading one and that's it. There may be some specific cases where reloading could be useful but in that case I would expect that:
Q3: Q4: having an overload for stream and another one for loader is clear enough for me. My concern here is more about signals going "too far" in what they should achieve in my opinion as I don't think they are good for streams... Q5: I can't find any at the moment Q6: I think it's great like this! Q7: I don't know if I would need something lower level to implement the resource contract for any external lib I would make BUT I would most probably need it if I created some fake services, using real resources in the Http instances and fake ones in Fake instances like InMemory for example! |
Beta Was this translation helpful? Give feedback.
-
RFC answer 1: RFC answer 2: RFC answer 3: RFC answer 4: RFC answer 6: Thanks for this RFC! <3 And guys, have a question (maybe, a stupid one): so, using a resource that make a fetch call to an api, will not trigger angular interceptor, right? I think this is a big difference between the two, if my understanding is correct. |
Beta Was this translation helpful? Give feedback.
-
We would like to thank everyone who commented on, or otherwise engaged in the discussion on this RFC.The API section alone got over 200 comments: responses to the RFC questions, new use-cases and many, many insights. The level of details and depth of the technical discussion was outstanding - the Angular community at its best! We went over every single comment, responded to many of them and discussed several patterns internally, in the team. Generally speaking the feedback can be broadly categorized into: “Resource as a concept” and “API design”. When it comes to the conceptual side of the new primitive we could see several main themes:
As for the API design, there was a lot of consensus around RFC questions and API shape in general. Based on the feedback you’ve shared we’ve decided to make the following changes:
Some of those changes landed already, some have open PRs or will have PRs opened. In any case we will make all the mentioned changes before releasing Angular v20. The Resource story in Angular is just starting and will be evolving. To reflect this, the resource APIs will remain experimental in Angular v20. We will persuade the stabilization process and embark on designing additional APIs and functionality in the subsequent releases. Your continued feedback is crucial: play with Angular v20, build on top of it and open GitHub issues for any problems or enhancements that should be considered. Thank you |
Beta Was this translation helpful? Give feedback.
-
Welcome to part 2 of the Resource RFC, covering the API design of Angular's initial resource integrations. Also check out the Resource RFC: Part 1 covering the Resource Architecture.
Resource APIs
There are a number of APIs that work together and provide a cohesive story for asynchronous reactivity. Those APIs can be categorized into 3 groups:
Resource (capital R) and related interfaces - this is the fundamental API, a contract where the framework and Angular developers agree on how asynchronous processing and resulting data are represented.
resource and related APIs - represents a generic and flexible resource primitive where data can be loaded asynchronously from a wide variety of storages.
httpResource - this is a specialized resource that makes it easy to load data exposed by HTTP endpoints.
The following sections cover APIs from each group in more detail. Note that in some cases, the APIs in this doc differ from the
@experimental
APIs already in Angular - this reflects planned updates we have not yet landed.Resource
The Resource interface exposes, first and foremost, data loaded asynchronously. The value represents data as a
Signal
since resources can update over time (for example, in response to reactive dependency changes). This is analogous to how the computed signal works - it exposes a signal whose value can change as the application runs and reactive expressions are recomputed.In addition to the value itself we also expose additional properties indicating if a value is ready, being loaded - or maybe is not available due to some processing errors. The error signal will hold an error instance if data load failed (and will be
undefined
if the load is in progress or finished successfully).More generally, resources transition through different states in response to changes in its reactive dependencies. Those states are enumerated in the ResourceStatus:
The current state is exposed as the status signal.
As a convenience, we expose 2 additional signals that makes it possible to quickly and conveniently check for common states:
isLoading signal will have the true value if the resource is in one of the Loading or Reloading states.
hasValue will have the true value if the
value
of the resource is not undefined. Note that this does not mean the resource is necessarily resolved. For example, the resource may have adefaultValue
other thanundefined
, in which casehasValue
will always betrue
.Note that
hasValue
is reactive, despite not being typed as aSignal
.RFC question 1: in the proposed API design resource status is of type ResourceStatus enum. ResourceStatus is a convenient namespace that collects all the statuses and makes them easily discoverable. At the same time using enums in Angular templates (ex.:
@if (myRes.status() === ResourceStatus.Error)
) requires exposing ResourceStatus on a component instance - this creates additional authoring friction.We do expect this friction to be alleviated over time, either through better support for enums and other imported symbols in templates, or a dedicated template syntax for working with resources. However, it's clear this friction will be felt early on. We’ve been considering exposing statuses as an union type of string literals (see #58920 for additional context).
What would be your preference when it comes to the status type?
RFC question 2: the experimental resource implementation distinguishes between the loading operation triggered by change to the reactive dependencies (
Loading
) and the one triggered imperatively (Reloading
). Generally, inLoading
state the resource has no current value, but inReloading
the resource keeps its value while reloading.Do you consider this distinction to be useful?
resource
The resource function is a factory that creates instances of ResourceRef (an owned flavor of the Resource interface). It projects a reactive state to an asynchronous operation defined by a loader function and finally exposes the result of loading as a Resource.
This is a rather generic and lower-level building block that is adequate for interacting with a wide variety of asynchronous data storages:
The request and loader functions (provided as options to the resource creation) work together to derive reactive, asynchronous data based on changes to the reactive state:
request
prepared by the previously mentioned request function. A loader is expected to return a promise that resolves with data to be exposed by a resource instance (or rejected in case of loading problems). The loader function is asynchronous and not reactive.RFC question 3: Our intention was to use a name for the parameter (currently called
request
) indicating that we are preparing all information necessary to make an actual request. The common point of feedback, though, is that this name might not clearly convey this intention and might be lacking context. What other name would you prefer here? On our side, we’ve also considered:params
,data
,requestParams
,source
, …Like effects, resources are owned by the component which creates them and thus require an injection context. Alternatively, you can provide a specific injector instance.
The optional equal function is passed to the signal representing a value.
Resource Loading
At the heart of the resource is its
loader
. This async function takes the currentrequest
of the resource and produces aPromise
of the resolved value.resource
will never resolve to a stale value, even if a loader continues to return data after the resource'srequest
has changed. Still, it's desirable to be able to cancel pending work if the results are no longer needed. To support this, loaders receive anAbortSignal
. This isn't an Angular signal, but a native browser API for responding to cancellation of work streams. A resource loader can use thisAbortSignal
to listen for cancellation and abort any pending work.streaming resource
The APIs described so far are well suited for the cases where an asynchronous data storage returns values in one response. There are other cases, though, where a server might respond in multiple chunks (for a given set of request parameters). As an example, a server might return the first n items of a list as soon as possible and follow up with more items in subsequent chunks / responses. To accommodate those use cases the resource comes with the stream option (alternative to the loader):
The streaming resource uses the same creation function discussed previously. Most of the options remain the same, but there is one important difference - the stream function is equipped to handle multiple responses for the same set of request parameters. To do so, the stream function returns a promise of a signal:
RFC question 4: the proposed design uses one resource function with a different set of parameters. Is this API making sufficient distinction between the streaming and non-streaming usage patterns?
rxResource
The streaming resource model of returning a
Promise
of aSignal
is a good signals-first model for streamed data, accounting for the initial period of asynchronicity and the changing nature of the resolved value over time. Existing applications often use Observables for this purpose.To that end, we're adding the
rxResource
utility to@angular/core/rxjs-interop
.rxResource
is configured similarly to the streaming flavor ofresource
, except thestream
loader produces Observables:The resulting resource tracks the value of the Observable over time, including if the Observable stream ends with an error.
httpResource
The
resource
API is a generic utility for wrapping asynchronous operations in resources. For most applications, the majority of data dependencies come in the form of HTTP operations. To facilitate this, we're introducinghttpResource
:httpResource
is a frontend for@angular/common/http
. It makes HTTP requests through the Angular HTTP stack, including interceptors and the testing utilities. It differs from theHttpClient
interface in several significant ways:Declaring an
httpResource
initiates the request eagerly (unlike theHttpClient
Observable-based requests which must be subscribed).Like
resource
, it configures a reactive request. If source signals in the request computation change, a new HTTP request will be made.It returns an instance of
HttpResourceRef
, which has additional signals for metadata about the response.httpResource
has two calling patterns: either it can be configured with a URL, or with an object describing a more complex request to make (e.g. a POST request to a query API with a body, headers, etc):In either case, the request can be configured as a static value or by passing a reactive function.
Like
resource
,httpResource
also supports adefaultValue
which overrides the normalundefined
value before the resource resolves.Non-JSON requests
By default,
httpResource
parses data returned by the backend as JSON. There are three other response types that Angular's HTTP stack supports: text,Blob
, andArrayBuffer
. To make those requests, sub-functions are available which alter the expected response:The other supported sub-functions are
httpResource.text()
andhttpResource.blob()
.RFC Question 5: We started using this style of API with
input.required
and we feel like the ergonomics work well here, with JSON being the default and other response types being accessible as sub-functions. Is there another API we should consider instead, like making each response type a top-level function?Type-safe HTTP responses
A goal of the
httpResource
design was to improve upon the type safety offered byHttpClient
, while preserving the convenience of being able to directly declare a response type in cases where more strict validation isn't necessary.By default,
httpResource
returns the "raw type" of the response. For JSON resources this isunknown
, for the others it's the returned object type (Blob
,string
, etc).For JSON resources, you can directly specify a response type, just as with
HttpClient
:This is equivalent to a type cast.
However, sometimes more strict type-checking is desirable. For example, often developers use runtime validation libraries like Zod to enforce type safety when dealing with external data sources.
httpResource
supports aparse
operation which can transform the resource's raw value into a different type, optionally performing validation in the process.For example, this snippet uses Zod to validate the shape of the backend response at runtime:
RFC Question 6: how do you feel about this approach to type safety? Have you seen alternative approaches in other HTTP integrations that we should consider instead?
Mutations
httpResource
(and the more fundamentalresource
) both declare a dependency on data that should be fetched. It's not a suitable primitive for making imperative HTTP requests, such as requests to mutation APIsCustom Resources
We see lots of desire and benefit for libraries to expose their own async operations via the
Resource
API. While this could be done by wrapping them withresource
, this might not be compatible with all potential use cases.We are considering including base utilities that developers can extend to produce their own implementations of
Resource
. These APIs are still being researched, and we're not far enough along to solicit feedback on them directly via this RFC. Instead, we would like to ask:RFC Question 7: if you maintain a library or other utility that could benefit from exposing results as
Resource
s, what opportunities and challenges do you see there? Would you be able to useresource()
to achieve this, or would you need something lower level to directly implement the resource contract?Beta Was this translation helpful? Give feedback.
All reactions