diff --git a/aip/general/0214/aip.md.j2 b/aip/general/0214/aip.md.j2 new file mode 100644 index 00000000..9798c378 --- /dev/null +++ b/aip/general/0214/aip.md.j2 @@ -0,0 +1,46 @@ +# Resource expiration + +Sometimes it is necessary for a resource to have a defined lifespan. At the end +of this lifespan, the resource expires but may still be accessible from the +server. The duration or end of this lifespan may be controled by an API client, +or determined by the server at the time of creation. Lifespans can be defined +as an absolute time value or as a relative time offset. An absolute time value +stored in the `expire_time` field is preferred. + +The `expire_time` of a resource is not intended to be a replacement for the `Cache-Control` header used to communicate client-side or CDN caching +recommendations. The lifespan of a resource refers to the time it spends in a +valid or actionable state, such as how long a certificate is valid, or how long +an auction is active. + +For some resources, a relative time offset may be more appropriate than an +absolute time value. Furthermore, the world understands the concept of a +"time-to-live", often abbreviated to TTL. However, the typical format of this +field (an integer, measured in seconds) results in a sub-par experience when +using an auto-generated client library. Nonetheless, a `ttl` field may be used +in conjunction with the `expire_time` field. + +## Guidance + +Services wishing to convey an expiration **must** rely on a timestamp field +called `expire_time`. Services wishing to allow a relative expiration time +**must** define a `oneof` called `expiration` (or `{something}_expiration`) +containing both the `expire_time` field and a separate [duration][aip-142] +field called `ttl`, the latter marked as input only: + +{% tab proto %} + +{% sample 'expiry.proto', 'message Book' %} + +{% tab oas %} + +{% sample 'expiry.oas.yaml', 'schema' %} + +{% endtabs %} + +Services **must** always return the expiration time in the `expire_time` field +and leave the `ttl` field blank when retrieving the resource. + +Services that rely on the specific semantics of a "time to live" (e.g., DNS +which must represent the TTL as an integer) **may** use an `int64 ttl` field +(and **should** provide an [aip.dev/not-precedent][aip-200] comment in this +case). diff --git a/aip/general/0214/aip.yaml b/aip/general/0214/aip.yaml new file mode 100644 index 00000000..7f367c86 --- /dev/null +++ b/aip/general/0214/aip.yaml @@ -0,0 +1,7 @@ +--- +id: 214 +state: approved +created: 2018-06-19 +placement: + category: design-patterns + order: 120 diff --git a/aip/general/0214/expiry.oas.yaml b/aip/general/0214/expiry.oas.yaml new file mode 100644 index 00000000..16cdd8be --- /dev/null +++ b/aip/general/0214/expiry.oas.yaml @@ -0,0 +1,26 @@ +--- +openapi: 3.0.3 +info: + title: Library + version: 1.0.0 +components: + schema: + Book: + description: This book will self-destruct. + properties: + name: + type: string + description: | + The name of the book. + Format: publishers/{publisher}/books/{book} + expire_time: + type: string + format: date-time + description: | + Timestamp in UTC of when this resource is considered expired. + This is *always* provided on output, regardless of what was sent + on input. + ttl_seconds: + type: integer + description: The TTL for this resource. + writeOnly: true diff --git a/aip/general/0214/expiry.proto b/aip/general/0214/expiry.proto new file mode 100644 index 00000000..5240fba0 --- /dev/null +++ b/aip/general/0214/expiry.proto @@ -0,0 +1,42 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +import "google/api/field_behavior.proto"; +import "google/api/resource.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +// This book will self-destruct. +message Book { + option (google.api.resource) = { + type: "library.googleapis.com/Book" + pattern: "publishers/{publisher}/books/{book}" + }; + + // The name of the resource; the format is: ... + string name = 1; + + oneof expiration { + // Timestamp in UTC of when this resource is considered expired. + // This is *always* provided on output, regardless of what was sent + // on input. + google.protobuf.Timestamp expire_time = 2; + + // Input only. The TTL for this resource. + google.protobuf.Duration ttl = 3 + [(google.api.field_behavior) = INPUT_ONLY]; + } +}