Skip to content
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(middleware): add sunset/deprecation header middleware #844

Merged
merged 3 commits into from
Oct 19, 2023

Conversation

thedevsaddam
Copy link
Contributor

@thedevsaddam thedevsaddam commented Sep 4, 2023

This PR will include a Sunset middleware which can be used to deprecate an endpoint or a group of endpoints.

For additional information please go through the LINK

Example usages

func main() {
	r := chi.NewRouter()

	sunsetAt := time.Date(2025, 12, 24, 10, 20, 0, 0, time.UTC)
	r.Use(middleware.Sunset(sunsetAt))

	// can provide additional link for updated resource
	// r.Use(middleware.Sunset(sunsetAt, "https://example.com/v1/deprecation-details"))

	r.Get("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("This endpoint will be removed soon"))
	})

	log.Println("Listening on port: 3000")
	http.ListenAndServe(":3000", r)
}

Copy link
Contributor

@VojtechVitek VojtechVitek left a comment

Choose a reason for hiding this comment

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

I like this feature. However, should we wait for the Sunset header to actually make it into an RFC?

middleware/sunset.go Outdated Show resolved Hide resolved
middleware/sunset.go Outdated Show resolved Hide resolved
middleware/sunset.go Outdated Show resolved Hide resolved
Copy link
Contributor

@VojtechVitek VojtechVitek left a comment

Choose a reason for hiding this comment

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

LGTM.

I think this is useful, especially since these headers are defined in RFC8594 - https://www.rfc-editor.org/rfc/rfc8594.html.

Let's see if @pkieltyka agrees this can be merged into github.com/go-chi/chi/v5/middleware :)

Respect previously added links as this header can be used by other
components
@pkieltyka
Copy link
Member

thanks for the PR @thedevsaddam and thanks for reviewing @VojtechVitek

@pkieltyka pkieltyka merged commit 3954a76 into go-chi:master Oct 19, 2023
14 checks passed
@thedevsaddam
Copy link
Contributor Author

thanks for the PR @thedevsaddam and thanks for reviewing @VojtechVitek

Thank you so much for this amazing package!

@johnmaguire
Copy link
Contributor

johnmaguire commented Oct 19, 2024

Pardon my curiosity - I saw this PR while browsing through the changelog.

I see that RFC 8594 defines the "Sunset" header but makes no mention of the "Deprecation" header.

I did find this IETF draft which mentions the "Deprecation" header but it seems to serve a slightly different purpose:

The purpose of the Deprecation header field is to provide a hint
about deprecation to the resource consumer. Upon reception of the
Deprecation header field, the client application developer can look
up the resource's documentation in order to find deprecation related
information. The documentation MAY provide a guide and timeline to
migrate away from the deprecated resource to a new resource(s)
replacing the deprecated resource, if applicable. The resource
provider can provide a link to the resource documentation using a
Link header field with relation type deprecation as shown below:

 Link: <https://developer.example.com/deprecation>;
       rel="deprecation"; type="text/html"

In this example the linked content provides additional information
about deprecation of the resource context. There is no Deprecation
header field in the response, and thus the resource is not (yet)
deprecated. However, the resource already exposes a link where
information is available describing how deprecation is managed for
the resource. This may be the documentation explaining under which
circumstances and with which policies deprecation might take place.
For example, a policy may indicate that deprecation of a resource(s)
will always be signaled in the dedicated places at least N days ahead
of the planned deprecation date and then only the resource(s) would
be deprecated. Or a policy may indicate that resource(s) would be
deprecated first and then only be signaled as deprecated at dedicated
places. The documentation in addition to the deprecation policy may
also provide a migration guide exaplaining to consumers of the
resource how to migrate to a new resource(s) or an alternate
resource(s) before the deprecation date. Such policy and
documentation would be very useful to consumers of the resource to
plan ahead and migrate successfully.

The following example uses the same link header field, but also
announces a deprecation date using a Deprecation header field:

 Deprecation: @1688169599
 Link: <https://developer.example.com/deprecation>;
       rel="deprecation"; type="text/html"

There is also mention of the Sunset header, which uses a different time format:

In addition to the deprecation related information, if the resource
provider wants to convey to the client application that the
deprecated resource is expected to become unresponsive at a specific
point in time, the Sunset HTTP header field [RFC8594] can be used in
addition to the Deprecation header field.

The timestamp given in the Sunset header field MUST NOT be earlier
than the one given in the Deprecation header field. If that happens
for some reasons such as misconfiguration of deployment of the
resource or an error, the client application developer SHOULD consult
the resource developer to get clarification.

The following example shows that the resource in context has been
deprecated since Friday, June 30, 2023 at 23:59:59 UTC and its sunset
date is Sunday, June 30, 2024 at 23:59:59 UTC. Please note that for
historical reasons the Sunset HTTP header field uses a different data
format for date.

 Deprecation: @1688169599
 Sunset: Sun, 30 Jun 2024 23:59:59 UTC

This PR returns both headers set to the same time and format:

w.Header().Set("Sunset", sunsetAt.Format(http.TimeFormat))
w.Header().Set("Deprecation", sunsetAt.Format(http.TimeFormat))

Perhaps the Deprecation header should be reverted until this draft is standardized?

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.

4 participants