-
Notifications
You must be signed in to change notification settings - Fork 714
Support Deprecation header #1151
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
base: main
Are you sure you want to change the base?
Conversation
|
@dotnet-policy-service agree |
|
Thanks for this. Just acknowledging that I've seen it. I'll try to put eyes on it ASAP. FYI, I'll be on vacation next week. I'm not ignoring it. 😉 |
|
Have you had any chance to look at this yet? |
commonsensesoftware
left a comment
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.
Overall, it looks great. I'd estimate that 90%+ of the work is there. There are a few open questions and minor tweaks to address, but this looks close to landing.
examples/AspNetCore/OData/ODataOpenApiExample/ConfigureSwaggerOptions.cs
Show resolved
Hide resolved
src/Abstractions/src/Asp.Versioning.Abstractions/ISunsetPolicyManager.cs
Outdated
Show resolved
Hide resolved
src/Abstractions/src/Asp.Versioning.Abstractions/DeprecationPolicy.cs
Outdated
Show resolved
Hide resolved
src/Abstractions/src/Asp.Versioning.Abstractions/DeprecationPolicy.cs
Outdated
Show resolved
Hide resolved
src/Abstractions/src/Asp.Versioning.Abstractions/SunsetPolicy.cs
Outdated
Show resolved
Hide resolved
src/Abstractions/src/Asp.Versioning.Abstractions/ISunsetPolicyBuilder.cs
Show resolved
Hide resolved
src/AspNetCore/WebApi/src/Asp.Versioning.Mvc.ApiExplorer/ApiDescriptionExtensions.cs
Show resolved
Hide resolved
src/AspNetCore/WebApi/test/Asp.Versioning.Http.Tests/DefaultApiVersionReporterTest.cs
Outdated
Show resolved
Hide resolved
8d1a6b6 to
064c5c9
Compare
|
Thanks for the thorough review! I went through everything and implemented all your suggestions. Hopefully this is in line with what you had in mind. Two or three comments are still open because it wasn't totally clear to me what the best course of action is. |
|
Looking good. I'll be traveling this weekend. With the holiday and traveling, it might be next week before I get to take a serious look. I just wanted you to know that am looking and your efforts are appreciated. 😉 |
|
Bump. Are you still traveling? From your previous comment, it seemed that this was at least going in the right direction, so in the meantime I'm going to get started on getting the tests green again and adding any tests that may be missing. |
|
I am traveling again, but I'm working remote. I'll get eyes on this tonight or tomorrow. Thanks for poking the bear. ;) |
commonsensesoftware
left a comment
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.
It's looking great. I think there are just a few niche cases and then this should be ready to go.
| /// </summary> | ||
| /// <param name="response">The <see cref="HttpResponseMessage">HTTP response</see> to read from.</param> | ||
| /// <returns>A new <see cref="DeprecationPolicy">deprecation policy</see>.</returns> | ||
| public static DeprecationPolicy ReadDeprecationPolicy( this HttpResponseMessage response ) |
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.
Is there a test for this? I'm not seeing it. It feel like there should definite should be one.
src/Abstractions/src/Asp.Versioning.Abstractions/ISunsetPolicyBuilder.cs
Show resolved
Hide resolved
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.
Since I ISunsetPolicyManagerExtensions.cs was deleted and supplanted by IPolicyManagerExtensions.cs, shouldn't this file be renamed to IPolicyManagerExtensionsTest.cs?
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.
Correct me if I'm wrong, but this looks/feels like we lost the extensions for ISunsetPolicyManager, no? Sunset policies can still build links and effective dates, even if they have a slightly different meaning from deprecation.
Based on the other thread on Link and Effective, I'm wondering if we're missing a couple of interfaces so we can describe the behavior independently and compose them. This would retain the flexibility of separate interface evolution, keep the 2 distinct interfaces, but still allow for a unified set of extension methods.
I'm not settled on the names, but I could imagine this being refactored into something like:
public interface ILinkSource
{
ILinkBuilder Link( Uri linkTarget );
}
public interface IPolicyEffectiveDate
{
void Effective( DateTimeOffset date );
}
public interface IDeprecationPolicyBuilder : IPolicyBuilder<DeprecationPolicy>, ILinkSource, IPolicyEffectiveDate { }
public interface ISunsetPolicyBuilder : IPolicyBuilder<SunsetPolicy>, ILinkSource, IPolicyEffectiveDate { }
public static class IPolicyBuilderExtensions
{
public static ILinkBuilder Link( this ILinkSource builder, string linkTarget )
{
ArgumentNullException.ThrowIfNull( builder );
return builder.Link( new Uri( linkTarget, UriKind.RelativeOrAbsolute ) );
}
public static TBuilder Effective<TBuilder>( this TBuilder builder, int year, int month, int day )
where TBuilder : notnull, IPolicyEffectiveDate
{
ArgumentNullException.ThrowIfNull( builder );
builder.Effective( new DateTimeOffset( new DateTime( year, month, day ) ) );
return builder;
}
}Thoughts?
| additionalInfo ); | ||
| } | ||
|
|
||
| [LoggerMessage( EventId = 1, Level = Warning, Message = "API version {apiVersion} for {requestUrl} has been deprecated and will sunset on {sunsetDate}. Additional information: {links}" )] |
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.
Shouldn't these log messages now include the date the API was deprecated if we know it from the deprecation policy?
| /// Gets the API deprecation policy. | ||
| /// </summary> | ||
| /// <value>The <see cref="DeprecationPolicy">deprecation policy</see> for the API.</value> | ||
| public DeprecationPolicy DeprecationPolicy { get; } |
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.
I don't see a change to the file, but shouldn't IsDeprecatedApi in ApiVersionHandler.cs now change also, at least, check and honor the deprecation policy, when present? In the absence of the policy, the current logic continues to make sense as a fallback.
|
@MGessinger One other important design aspect I wanted to think about and discuss is what we think the intersection of the new deprecation policy should be the existing APIs and metadata. As an example, the A user can specify: [ApiController]
[ApiVersion(0.9, Deprecated = true)]
[Route("[controller]")]
public class ExampleController
{
[HttpGet]
public string Get() => Ok("Demo");
}This controller expresses that it supports version Conversely, options.Policies.Deprecate( 0.9 )
.Effective( DateTimeOffset.Now.AddDays( 60 ) )indicates that all The question becomes "How do we think about precedence?". I think the precedence would be ranked as:
I suspect there's some checks in the implementation that have been missed. Today, things are solely based on |
Add new policy to configure
Deprecationheader fieldAdd a new
DeprecationPolicywhich emits aDeprecationheader when a matching API version is used.Description
An API may emit a
Deprecationheader to inform clients that a resource is/will become deprecated (but may still be available past that point). The newDeprecationPolicyallows users to configure this header, as well as the (optional) associated links. This is analogous to the existingSunsetPolicy.The implementation follows the existing
SunsetPolicy(and associated classes likeSunsetPolicyBuilder,SunsetPolicyManageretc) as closely as possible. In an attempt to minimize code duplication between the two, common functionality was extracted into shared base classes/interfaces. There is still some duplication left over, but I chose what seemed like a reasonable a middle ground between streamlining the two policies, and keeping the code clear.At the time of writing this, no tests have been added yet. Since this is a rather large PR with many changed files, I want a second opinion on the implementation before I start pinning everything down in tests. I did at least verify that the solution compiles.
Design choices
This summarizes the linked issue #1128
The new policy is configured like this:
deprecationas per the spec.Fixes #1128