From c2b1c57831dabe037123679d781742508e9c669f Mon Sep 17 00:00:00 2001 From: Yusuke Tsutsumi Date: Sat, 28 Feb 2026 10:48:47 -0800 Subject: [PATCH] feat(122): add missing OAS guidance 122 has guidance that is specific to proto, causing confusion when trying to apply it to OAS. Clarifying OAS guidance. --- aep/general/0122/aep.md.j2 | 86 +++++++++++++++++++++++++++++++++++--- scripts/build.sh | 37 ++++++++++------ 2 files changed, 104 insertions(+), 19 deletions(-) diff --git a/aep/general/0122/aep.md.j2 b/aep/general/0122/aep.md.j2 index fe684aef..c3ca43d2 100644 --- a/aep/general/0122/aep.md.j2 +++ b/aep/general/0122/aep.md.j2 @@ -194,10 +194,16 @@ and the full resource path does not change between these. ### Fields representing resource paths -When defining a resource, the first field **should** be the resource path, -which **must** be of type `string` and **must** be called `path` for the -resource path. The message **should** include a `aep.api.resource` annotation -declaring the type (see AEP-4 for more on this). +When defining a resource, the first field: + +- **should** be the resource path, + - **must** be of type `string` + - **must** be called `path` + - **must** be read-only +- The message **should** include a `aep.api.resource` annotation declaring the + type (see AEP-4 for more on this). + +{% tab proto %} ```proto // A representation of a book in the library. @@ -209,7 +215,7 @@ option (aep.api.resource) = { // The resource path of the book. // Format: publishers/{publisher_id}/books/{book_id} -string path = 1; +string path = 1 [ (aep.api.field_info) = { field_behavior: [ FIELD_BEHAVIOR_READONLY ] } ]; // Other fields... } @@ -238,8 +244,33 @@ string path = 1 [ other use cases, either use a different term or prepend an adjective (for example: `file_path`). +{% tab oas %} + +```yaml +components: + schemas: + book: + type: object + properties: + path: + type: string + description: + 'The resource path of the book. Format is + `publishers/{publisher_id}/books/{book_id}`' + readOnly: true + shelf: + type: string + description: + 'The shelf where the book currently sits. Format is + `shelves/{shelf}`' +``` + +{% endtabs %} + ### Fields representing a resource's parent +{% tab proto %} + When defining a method that retrieves resources from a collection or adds a new resource to a collection (such as `ListBooks` or `CreateBook`), the first field of the request message **should** be of type `string` and **should** be called @@ -278,6 +309,23 @@ string parent = 1 [ ``` **Note:** Fields **should not** be called `parent` except for this purpose. For + +{% tab oas %} + +When defining a method that retrieves resources from a collection or adds a new +resource to a collection (such as `ListBooks` or `CreateBook`), the path of the +parent resource **must** be a prefix to the path of the collection: + +``` +# ListBooks +GET /v1/publishers/{publisher_id}/books + +# CreateBook +POST /v1/publishers/{publisher_id}/books +``` + +{% endtabs %} + other use cases, use a synonymous term if possible. ### Fields representing another resource @@ -286,7 +334,7 @@ When referencing a resource path for a different resource: - The field **must** be of type `string`. - The value of the field **must** be one of: - - the full resource path. + - the full resource path (including the API service hosting the resource). - the resource path, only if the referenced resource is also local to the API of the current resource. - The field name **should** be equivalent to the corresponding message's name @@ -295,6 +343,9 @@ When referencing a resource path for a different resource: `string dusty_book`). - Field names **should not** use the `_path` suffix unless the field would be ambiguous without it (e.g., `crypto_key_path`) + +{% tab proto %} + - In protobuf, fields representing another resource **should** provide the `aep.api.field_info` annotation with the resource type being referenced. @@ -318,6 +369,29 @@ string shelf = 2 [(aep.api.field_info) = { resource_reference: [ "apis.example.c } ``` +{% tab oas %} + +```yaml +components: + schemas: + book: + type: object + properties: + path: + type: string + description: + 'The resource path of the book. Format is + `publishers/{publisher_id}/books/{book_id}`' + readOnly: true + shelf: + type: string + description: + 'The shelf where the book currently sits. Format is + `shelves/{shelf}`' +``` + +{% endtabs %} + **Note:** When referring to other resources in this way, APIs **should** use the resource path to reference resources when possible. If using the ID component alone is strictly necessary, the field **should** use an `_id` suffix diff --git a/scripts/build.sh b/scripts/build.sh index e0a31aa5..84393ccf 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,22 +1,33 @@ #!/usr/bin/env bash +# build the AEPs +# For development purposes, it's best to lay out the other aep repositories +# side by side from the primary AEPs. If so, this script will use the +# site-generator and api-linter from those sibling directories. +# Otherwise, it will clone dependencies. set -x export AEP_LOCATION="${PWD}" -export SG_DIRECTORY="/tmp/site-generator" -export AEP_LINTER_LOC="${SG_DIRECTORY}/api-linter" -export AEP_OPENAPI_LINTER_LOC="${SG_DIRECTORY}/aep-openapi-linter" -if [ ! -d "${SG_DIRECTORY}" ]; then - git clone https://github.com/aep-dev/site-generator.git "${SG_DIRECTORY}" -fi -if [ ! -d "${AEP_LINTER_LOC}" ]; then - git clone https://github.com/aep-dev/api-linter.git "${AEP_LINTER_LOC}" -fi +declare -A repos -if [ ! -d "${AEP_OPENAPI_LINTER_LOC}" ]; then - git clone https://github.com/aep-dev/aep-openapi-linter.git "${AEP_OPENAPI_LINTER_LOC}" -fi +repos=( + [site_generator]="site-generator" + [api_linter]="api-linter" + [aep_openapi_linter]="aep-openapi-linter" +) -cd "${SG_DIRECTORY}" || exit +for varName in "${!repos[@]}"; do + repoName="${repos[$varName]}" + if [ -d ${AEP_LOCATION}/../${repoName} ]; then + eval "$varName=${AEP_LOCATION}/../${repoName}" + else + eval "$varName=/tmp/${repoName}" + if [ ! -d "${varName}" ]; then + git clone https://github.com/aep-dev/$repoName.git "${!varName}" + fi + fi +done + +cd "${site_generator}" || exit # make rules / website folder mkdir -p src/content/docs/tooling/linter/rules mkdir -p src/content/docs/tooling/openapi-linter/rules