Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sections of annotation and annotation (keyword) in the glossary #668

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

bhavukkalra
Copy link
Contributor

@bhavukkalra bhavukkalra commented Apr 20, 2024

What kind of change does this PR introduce?
As discussed in the issue #266. This PR adds two very similar sections to the glossary section.

Screenshots/videos:
image

Summary
This PR is a part of the individual PR's getting created for completing the glossary page. Used these as a reference to draft the description of these two related sections

Does this PR introduce a breaking change?
No

@bhavukkalra bhavukkalra requested a review from a team as a code owner April 20, 2024 16:23
Copy link
Member

@gregsdennis gregsdennis left a comment

Choose a reason for hiding this comment

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

I'm not sure where the language of "self-reliant" and "self-documenting" is coming from. (I'm not sure how "self-reliant" applies.) Annotations can do more than just documentation. They can provide context to validations ("Which subschema validated this data?"), they can append additional information to data (which is kinda what hyperschema does), and they can provide the host application with additional details for it to know how to continue processing the data.

These definitions, to me, don't seem to align with what annotations are.

Annotation keywords are merely keywords which produce annotations.

@@ -149,6 +149,23 @@ The JSON Schema specification includes a number of vocabularies which cover each

In some [dialects](#dialect) of JSON Schema, the `$vocabulary` keyword can be used to include the keywords defined by a vocabulary into the dialect, as well as to indicate whether implementations must specifically recognize the vocabulary in order to be able to process schemas written in the dialect or not.

### Annotation

Annotation is a piece of metadata attached to a piece of code, used to convey additional information about the code like its workings, the algorithm that it internally uses, etc.
Copy link
Member

Choose a reason for hiding this comment

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

This is a good general definition of an annotation, but let's come up with something a little more focused on JSON Schema. What does an annotation do for instance data?


Annotation is a piece of metadata attached to a piece of code, used to convey additional information about the code like its workings, the algorithm that it internally uses, etc.


Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

@benjagm benjagm added the Status: In Progress This issue is being worked on, and has someone assigned. label Apr 23, 2024
@jdesrosiers
Copy link
Member

jdesrosiers commented Apr 30, 2024

I generally agree with Greg's review. I don't know what "self-reliant" means in this context. People often use annotation keywords (not annotations) to make a schema "self-documenting", but they're not really using them as annotations in that case. I would describe an annotation as meta-data associated with a particular value in a JSON instance. An annotation keyword is an instruction to the validator on how and where to associate an annotation to the instance. That annotation can be used for all sorts of things. It could even be used for different things depending on the context. So, people using title and description to document their schema ("self-documenting"), they may be using annotation keywords, but they aren't using annotations because the annotation doesn't exist until you apply the schema to an instance.

I'll give a simple example and a more complex one. Here's the simple example.

Given an instance:

{
  "foo": "some value"
}

And a schema:

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "title": "Foo"
    }
  }
}

If I apply the schema to the instance, the result is an annotated instance. I'm using a made-up syntax for annotated JSON. Hopefully it makes sense.

{
  "foo": "some value" @title("Foo")
}

The value of /foo is "some value", but that value now has a title annotation attached to it. In theory, you would pass this annotated instance to some process to do something with it that does something with that annotation.

For the more complex example, consider that annotations aren't always just the value of the annotation keyword, they could be computed in some way to get the actual value that will be attached to the instance. Here's a JSON Hyper-Schema example of attaching a link to an instance.

Start by retrieving an instance from an API: https://example.com/api/widgets?page=1

HTTP/1.1 200 OK
Content-Type: application/json
Link: </schemas/widget-list>; rel="describedby"

{
  "list": [...],
  "page": 1,
  "per-page": 10,
  "next-page": 2
}

The instance identifies the schema that describes it using the "describedby" link, so we need to retrieve the schema as well.

HTTP/1.1 200 OK
Content-Type: application/schema+json

{
  "type": "object",
  "properties": {
    "list": { "type": "array" },
    "page": { "type": "integer" },
    "per-page": { "type": "integer" },
    "next-page": { "type": "integer" }
  },
  "links": [
    { "rel": "next", "href": "/api/widgets?page={next-page}" }
  ]
}

Then we apply the schema to the instance to get an annotated instance:

{
  "list": [...],
  "next-page": 2
} @links({ next: "https://example.com/api/widgets?page=2" })

Notice that the resulting meta-data fills in the URI Template and resolves the relative URI against the retrieval URI of the instance. A hyper-schema client can then use that annotated instance to get the next page in the list of widgets using the computed "next" link annotation.

// Get an annotated instance
const widgetList = HyperSchema.get("https://example.com/api/widgets");

// Iterate over the list automatically following "next" links as necessary to get all the widgets.
for await (const widget of HyperSchema.iter(widgetList)) {
  console.log(widget);
}

This is is a fictitious library that I still delude myself that I'll find time to write one day, but it hopefully gives a more concrete example of the kinds of things a hyper-schema client could do with link annotations.

@benjagm
Copy link
Collaborator

benjagm commented May 16, 2024

We did a good progress with the review of this PR. Are you still working on it Bhavuk?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: In Progress This issue is being worked on, and has someone assigned.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants