New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(common): http client request metadata for use in interceptors #25751
Conversation
a439a18
to
9688390
Compare
I am still alive and interested in updating this PR, so let me know if I should do anything |
@FDIM You may want to resolve the conflict if you are still around & interested. |
9688390
to
59ae2ee
Compare
59ae2ee
to
053e2f0
Compare
PR is ready again, failure in circle ci seems to be unrelated to my change |
Hey guys. Where are we at with this? Any idea on why CI is failing? |
FYI - I asked the Angular team in ngConf 2019 about this feature. The answer was, that this was one of the most requested feature and they have to wait for things to settle before adding this. So, it might be very unlikely for them to accepting this PR as-is. |
@un33k - what does "wait for things to settle" refer to? Just curious as I'm not quite sure what that means. |
@BobDankert ... I interpret it as |
@BobDankert Check out the closing remarks at ng-conf 2019 - Timeline: 21:04. |
Any update? Can I help somehow .. ? |
Why is this PR not yet approved?! |
@un33k oh that was you at ng-conf, awesome! To expand on my answer there a little bit: One of the big design questions here is whether metadata should be mutable or immutable. There are pros and cons to both:
My instinct there is that immutable is the way to go. It's how the rest of the API already works, and you can always add an object to the metadata early and make use of its interior mutability if needed. So assuming that's the direction we decide to go, the question becomes how to implement it. We have two immutable "map" types in If we introduce a third immutable container for metadata, it makes sense to refactor |
Thank you @alxhub for the response. Immutable metadata would be sufficient for our projects use cases. |
Yep, it seems like a logical and necessary step. But from the timeline point of view, do you expect some extra phases to do that? Can they significantly delay the realization? |
@alxhub Yep that was me asking the question and hopefully we can once again attend ng-config in person soon. As far the immutability goes, I think it can be just like the HttpParams and/or HttpHeaders. Right now, I piggyback some metadata onto HttpHeaders and have a no-op interceptor placed at the end which is responsible to peel the data off. It works well, but it would be great to have a native solution. |
There's been already 2 years of this PR trying to go into release... Perhaps a quick and separate implementation to make it fully available for us and leave the refactor with all the nice details for later? Just for the sake of availability and readiness.
I do the exact same thing on my end. Have to add some extra header so I can use as flag for some functionality I need and then remove it so it doesn't get sent with the actual backend request. |
bttt |
@FDIM be nice to have this ticket closed, so we can open a new one. Otherwise the new one is going to be redirected to this one and we end up in an infinite no-op loop. |
@un33k I'm still interested to finish this, but I have no idea who can make the decision. So this is stuck until someone from core team gets back. |
@FDIM Thanks for your cool PR. I'm also interested by this feature. Just a details, I will rename |
@FDIM thanks for your continued work on this feature. I think there's still some work to be done on the design, but this is definitely functionality that's been missing from After reviewing the current version and considering the API at a high level, I think a very simple design is preferable. @CodeTroopers suggestion of the So here's what I'm thinking:
This second point is a departure from my previous intuition, which is that request metadata should use the same immutable API as the rest of The amount of code to implement this is surprisingly small. Here's my concept of what export class HttpContextKey<T> {
constructor(readonly defaultValue: T) {}
}
export class HttpContext {
private map = new Map<HttpContextKey<unknown>, unknown>();
read<K>(key: HttpContextKey<K>): K {
return this.map.has(key) ? this.map.get(key) as K : key.defaultValue;
}
write<K>(key: HttpContextKey<K>, value: K): void {
this.map.set(key, value);
}
keys(): IterableIterator<HttpContextKey<unknown>> {
return this.map.keys();
}
} That's it. Each new Note that using a Beyond the implementation above, we'll need:
|
You can preview 2da0028 at https://pr25751-2da0028.ngbuilds.io/. |
You can preview 557dae0 at https://pr25751-557dae0.ngbuilds.io/. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed-for: public-api
Reviewed-for: size-tracking
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🍪
reviewed-for: size-tracking
557dae0
to
4cba236
Compare
You can preview 4cba236 at https://pr25751-4cba236.ngbuilds.io/. |
A long-requested feature for HttpClient is the ability to store and retrieve custom metadata for requests, especially in interceptors. This commit implements this functionality via a new context object for requests. Each outgoing HttpRequest now has an associated "context", an instance of the HttpContext class. An HttpContext can be provided when making a request, or if not then an empty context is created for the new request. This context shares its lifecycle with the entire request, even across operations that change the identity of the HttpRequest instance such as RxJS retries. The HttpContext functions as an expando. Users can create typed tokens as instances of HttpContextToken, and read/write a value for the key from any HttpContext object. This commit implements the HttpContext functionality. A followup commit will add angular.io documentation.
4cba236
to
7ec7207
Compare
You can preview 7ec7207 at https://pr25751-7ec7207.ngbuilds.io/. |
Caretaker Note: This has been merged. |
@FDIM You finally did it! Thank you very much for your perseverance, and ultimately this contribution. |
I'm so happy that this finally made it into the framework and looking forward to cleaning up misused headers! |
so many years but it's finally there!!!! |
great work! this is big :) |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Currently there is no way to configure interceptors in http client on per request basis and people (including myself) are abusing headers to disable / customize the behavior of certain interceptor (e.g. logging / authentication).
Issue Number: Fixes #18155
What is the new behavior?
This PR introduces a
context
option to any request that allows you to supply arbitrary data in a type safe way:There are also
get
,delete
, andkeys
methods onHttpContext
.set
andremove
can be chained to simplify usage.Does this PR introduce a breaking change?
Other information
~~There is another PR open since last year but have seen no activity since January - probably due to other comments on the issue and lost type safety. ~~
Also,HttpInterceptorMetadata
class is very generic (except for the name), maybe something like that could belong in core (or common?) package if there is a need?EDIT: Description has been updated to match latest implementation