Skip to content

Entity validation using schema fragments with external entity types - #116

Open
john-h-kastner-aws wants to merge 1 commit into
mainfrom
rfc-validating-entities
Open

Entity validation using schema fragments with external entity types#116
john-h-kastner-aws wants to merge 1 commit into
mainfrom
rfc-validating-entities

Conversation

@john-h-kastner-aws

@john-h-kastner-aws john-h-kastner-aws commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Rendered

Checklist

  • Added RFC to text/SUMMARY.md in numerical order

Signed-off-by: jkastner <jkastner@amazon.com>

Following the same basic design, there are some alternative syntax options to consider.

* We could use a different keyword: `extern`, shorter, also used by C and Rust; `import`, perhaps wrongly gives the impression that we're loading in an entity definition from somewhere; `use`, similar to `import`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the use of external or extern rather than use / import, which to me implies that we have access to the definition of the imported entity. extern makes it clear this is just a symbol that is declared externally.


When combining multiple fragments, we will attempt to link external entity type declarations with concrete definitions. Entity types are linked when their names match precisely (accounting for any containing namespace), but may never be linked with a builtin or common type definition even if the names are the same. An entity type may be declared as external any number of times, but it may only have one concrete definition across all schema fragments. If there is a definition, then that entity type becomes concrete in the resulting fragment, and is treated exactly the same as any other entity type. When there is no concrete definition the entity type remains external in the resulting fragment, but we do not report an error.

If every external entity type in a fragment has a corresponding definition, then the fragment is fully concrete. We can construct a complete `Schema` from it and use it exactly as if there were no external entity type declarations. In this situation, external declarations act as a helpful tool for schema authors to explicitly specify the dependencies between different schema fragments, but could be omitted entirely.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: it says fully concrete but later refers to complete, I prefer complete to talk about a complete or closed schema with no unresolved external references.

## Alternatives

* All undefined type names are assumed to be entity types. This isn't actually an alternative, but it's worth looking at why we can't do this. Schema fragments already have a meaning in which an undefined name may legitimately refer to a common type or action defined in another fragment. Assuming that every unresolved reference is an entity type would silently reinterpret those references and change the meaning of existing fragments, so a fragment could no longer be composed with the definitions it was actually written against. We might also frame this as a soundness issue — an entity that validated against a fragment could fail to validate against the complete schema.
* Add syntax for tagging the kind of type reference when it's used. E.g., `other: B::<entity>`. If `B` is defined as an entity, then it resolves to `B`, otherwise `B` is assumed to be external. This could also be useful for resolving ambiguity when a schema defines `B` as a common type and an entity type. I don't like this option because it doesn't explicitly say that `B` is external, just that it's an entity. We also wouldn't be able to detect simple typos like `Usr` instead of `User` before building the complete schema.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I didn't understand that part, is <entity> a tag that would indicate what kind of type B is?


To validate a `User` entity we would check that all elements of `my_actions` are one of the declared instances of `Shared::Action`.

We could not validate a request which applies to an external action.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Beyond this limitation, are there other reasons we should not consider an extension to actions?

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.

2 participants