Skip to content

Conversation

@MGessinger
Copy link

Add new policy to configure Deprecation header field

Add a new DeprecationPolicy which emits a Deprecation header when a matching API version is used.

Description

An API may emit a Deprecation header to inform clients that a resource is/will become deprecated (but may still be available past that point). The new DeprecationPolicy allows users to configure this header, as well as the (optional) associated links. This is analogous to the existing SunsetPolicy.

The implementation follows the existing SunsetPolicy (and associated classes like SunsetPolicyBuilder, SunsetPolicyManager etc) 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:

options.Policies.Deprecate( 0.9 )
                .Effective( DateTimeOffset.Now.AddDays( 60 ) )
                .Link( "deprecation.html" )
                    .Title( "Deprecation Policy" )
                    .Type( "text/html" );
  • When a deprecation policy is configured, then it will alwys be omitted, regardless whether the deprecation date is in the future or in the past.
  • The RelationType of the configured link must be deprecation as per the spec.
  • There is no constraint on the provided media type of the link.

Fixes #1128

@MGessinger
Copy link
Author

@dotnet-policy-service agree

@commonsensesoftware
Copy link
Collaborator

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. 😉

@MGessinger
Copy link
Author

Have you had any chance to look at this yet?

Copy link
Collaborator

@commonsensesoftware commonsensesoftware left a 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.

/// <param name="sunsetDate">The <see cref="DateTimeOffset">date and time</see> when a
/// sunset policy is applied.</param>
/// <returns>The current <see cref="ISunsetPolicyBuilder">sunset policy builder</see>.</returns>
ISunsetPolicyBuilder Effective( DateTimeOffset sunsetDate );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this were to return IPolicyBuilder<TPolicy> with slightly more generic wording for the date parameter and comments, Effective could be rolled up into the IPolicyBuilder<TPolicy> interface and get rid of this interface, no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, I can write something like policyBuilder.Effective( DateTimeOffset.Now ).Link(/*...*/). If I change the return type of Effective to be the base interface IPolicyBuilder, then this chained call only works if I pull Link into the base interface as well. To do that, I need to pull the implementation of Link from SunsetPolicyBuilder into the base PolicyBuilder, and to do that I need to get rid of SunsetLinkBuilder.
That seems like an awfully big refactoring to get rid of an interface, but maybe I'm missing an easy way out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thiing I could do is to pull Effective and Link into IPolicyBuilder but leave the implementation of Link in PolicyBuilder<TPolicy> as abstract. That would avoid most of the refactoring needed to make Link work while winning the benefit related to Effective.
But is it right to have Link in the base PolicyBuilder? For the policies that exist currently, yes. But will there be other policies?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I think that would be OK, but let me look at this some more.

@MGessinger
Copy link
Author

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.

@commonsensesoftware
Copy link
Collaborator

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. 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for the "Deprecation" Response Header (RFC 9745)

2 participants