-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Define common components for oneof parity across protobuf and OAS.
- Loading branch information
Showing
3 changed files
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
$schema: https://json-schema.org/draft/2020-12/schema | ||
$id: https://aep.dev/component.oneof.json | ||
title: x-aep-oneof | ||
description: | | ||
Represents a mutual exclusion constraint over multiple properties. | ||
It is an error for any properties specified by a oneof to be required. | ||
type: object | ||
required: [properties] | ||
additionalProperties: false | ||
properties: | ||
properties: | ||
description: | | ||
A set of properties that are mutually exclusive. | ||
type: array | ||
items: | ||
type: string | ||
required: | ||
description: | | ||
If set, exactly one property from the `properties` array must be present on the object. | ||
type: string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
syntax = "proto3"; | ||
|
||
package aep.api; | ||
|
||
option cc_enable_arenas = true; | ||
option go_package = "aep.dev/api"; | ||
option java_multiple_files = true; | ||
option java_outer_classname = "OneOfBehaviorProto"; | ||
option java_package = "dev.aep.api"; | ||
option objc_class_prefix = "AEP"; | ||
|
||
import "google/protobuf/descriptor.proto"; | ||
|
||
// Used to specify the behavior of a `oneof`. | ||
message OneOfBehavior { | ||
// If set, one field within the `oneof` must be set. | ||
// | ||
// When unset, the `oneof` is implicitly optional (the default behavior in | ||
// protobuf). | ||
bool required = 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# Oneof | ||
|
||
As used by the [AEPs](http://aep.dev), a `oneof` represents a set of mutually | ||
exclusive fields. | ||
|
||
## Schema | ||
|
||
Rather than a generic schema for `oneof`, we provide common components | ||
supplementing the language features of specific IDLs. Using these enables | ||
uniform behavior (and JSON serialization) across IDLs. | ||
|
||
### protobuf | ||
|
||
Protobuf's built-in `oneof` supports mutual exclusion of fields. However, it | ||
does not have a way for an API indicate that at least one of the fields must be | ||
set. For this purpose, a protobuf `oneof` may be annotated with | ||
[`aep.api.OneOfBehavior`](../proto/aep-api/aep/api/oneof_behavior.proto): | ||
|
||
```proto | ||
message Document { | ||
// ... | ||
// The owner of the document. | ||
oneof owner { | ||
// The user who owns the document. | ||
string user = 1 [(google.api.resource_reference) = { | ||
type: "apis.example.com/User", | ||
}]; | ||
// The group that owns the document. | ||
string group = 2 [(google.api.resource_reference) = { | ||
type: "apis.example.com/Group", | ||
}]; | ||
} [(aep.api.OneOfBehavior) = {required: true}]; | ||
} | ||
``` | ||
|
||
### OAS | ||
|
||
OAS 3 has a concept called `oneOf`, but it has different semantics than the | ||
`oneof` defined by this document; the OAS concept says that a single field must | ||
match exactly one of multiple possible schemas, rather than specifying mutual | ||
exclusion over multiple properties. | ||
|
||
In order to represent a `oneof` in OAS, in a way that produces JSON equivalent | ||
to that of protobuf, we define an extension `x-aep-oneof`: | ||
|
||
```yaml | ||
components: | ||
schemas: | ||
Document: | ||
type: object | ||
properties: | ||
user: { type: string } | ||
group: { type: string } | ||
x-aep-oneof: | ||
name: owner | ||
properties: [user, group] | ||
required: true | ||
``` | ||
The `x-aep-oneof` extension is used to indicate that at least one of the fields | ||
in the `oneOf` array must be set. | ||
|
||
**Note:** OAS extension not yet defined. |