Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 80 additions & 6 deletions aep/general/0122/aep.md.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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...
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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.

Expand All @@ -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
Expand Down
37 changes: 24 additions & 13 deletions scripts/build.sh
Original file line number Diff line number Diff line change
@@ -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
Expand Down