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

Things API with optional CRUD #273

Merged
merged 17 commits into from
Feb 21, 2022
Merged
Show file tree
Hide file tree
Changes from 12 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
5 changes: 4 additions & 1 deletion directory.tm.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
],
"title": "Thing Description Directory (TDD) Thing Model",
"version": {
"model": "1.0.0-alpha"
"model": "1.0.0-beta"
},
"base": "{{DIRECTORY_BASE_URL}}",
"tm:required": [
"#/properties/things"
],
Copy link
Member Author

Choose a reason for hiding this comment

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

The things property has two forms. One is for array payload which is mandatory, another is for the collection payload which is optional. To define this required form, the TM should support setting of a form to required using a nested required: true field. It currently doesn't.

I am setting the whole property to required, assuming that it means at least one form should offer this interaction. I can also set to #/properties/things/forms/0 but that means we are forcing the order of items in the forms array.

This was discussed in #253 (comment)

Copy link
Member

Choose a reason for hiding this comment

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

TBH, I think that for now having only things property required is fine. I know that it is clearly depicting the whole picture but we have normative statements that cover that part. I would wait for the TD spec to catch up and deal with this kind of issue (I would say that the issue here is much more complex than just requiring that a derived TD must have a specific form).

Copy link
Contributor

Choose a reason for hiding this comment

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

OK for now with this resolution, but I'm wondering now if we should not have two different interactions here. The expectation in TDs are that different forms are somehow equivalent, not for different purposes. The scripting API, for example, also assumes that any form in an interaction will do the same thing as any other.

Copy link
Member Author

Choose a reason for hiding this comment

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

They are equivalent ways of getting the TDs. The only difference is payload and header formats.

Copy link
Contributor

Choose a reason for hiding this comment

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

Discussion: Farshids thinks this is broken (maybe messed up as part of an earlier PR) and needs to be fixed. McCool thinks at the very least that putting forms distinguished by different contentTypes in a single interaction is inconvenient for Consumers. Farshid will create an issue and will investigate.

"properties": {
"things": {
"description": "Retrieve all Thing Descriptions",
Expand Down
161 changes: 120 additions & 41 deletions index.html
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -876,41 +876,96 @@ <h3>Directory Service API</h3>
incremental transfer of the payloads.
</p>

<p>
The directory APIs include mandatory, recommended, and optional
mmccool marked this conversation as resolved.
Show resolved Hide resolved
features.
Directories that don't offer recommended or optional features
inform the clients about the absence of those features
according to the following rules:
<ul>
<li>
If the missing feature is to customize existing functionality of an
API, the server will respond with 501 (Not Implemented)
Copy link
Contributor

Choose a reason for hiding this comment

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

will -> MUST assertion?

Copy link
Member Author

Choose a reason for hiding this comment

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

Assertions are in the respective sections as explained below:

The normative behavior is prescribed in the respective sections.

HTTP status.
For example, if a client requests a list of
items with a particular sorting order, the server either
respects that request and returns the list with the requested
mmccool marked this conversation as resolved.
Show resolved Hide resolved
order, or rejects the request and does not return the list.
The server will return the list with the default order
if and only if custom sorting is not requested.
The normative behavior is prescribed in the respective sections.
</li>
<li>
<span class="rfc2119-assertion" id="tdd-http-missing-api-endpoint">
If an API endpoint is not provided, the server SHOULD respond with
404 (Not Found).</span>
</li>
</ul>
</p>

<section id="exploration-directory-api-registration" class="normative">
<h4>Registration</h4>
<h4>Things API</h4>
<p>
The Registration API is a RESTful HTTP API in accordance with the recommendations
defined in [[RFC7231]] and [[?REST-IOT]].
<span class="rfc2119-assertion" id="tdd-reg-default-representation">
The default serialization format for all request and success response bodies MUST be
JSON, with JSON-LD 1.1 [[JSON-LD11]] syntax to support extensions and semantic
processing.
</span>
<span class="rfc2119-assertion" id="tdd-reg-additional-representation">
Directories MAY accept additional representations based on request's indicated
Content-Type or Content-Encoding, and provide additional representations through
server-driven content negotiation.
</span>
The Things API is a RESTful HTTP API served at the `/things` endpoint
providing interfaces to
create, retrieve, update, delete, and list (CRUDL) <a>TDs</a>.
The design of this API is in accordance with [[RFC7231]] and [[?REST-IOT]].
</p>
<p>
<span class="rfc2119-assertion" id="tdd-reg-crudl">
The Registration API MUST provide interfaces to
create, retrieve, update, delete, and list (CRUDL) <a>TDs</a>.
</span>

The operations are described below:
<p>
The HTTP API follows these general rules:
<ul>
<li>
<span class="rfc2119-assertion" id="tdd-reg-list-only">
The API MUST provide the interface to list TDs.</span>
The Search API allows filtering and selection from this list; see
[[[#exploration-directory-api-search]]].
</li>
<li>
<span class="rfc2119-assertion" id="tdd-reg-crud">
The API MAY provide the interfaces to
create, read, update, and delete (CRUD) individual TDs.</span>
</li>
<li>
A directory that provides both read and write over HTTP is considered
a full HTTP directory.
<span class="rfc2119-assertion" id="tdd-reg-crudl">
Full HTTP directories SHOULD implement all of
CRUDL (create, read, update, delete, and list) interfaces.</span>
It is practical to implement only the interfaces to read and list
if the directory serves a static collection of <a>TDs</a>.
This is also useful for directories that intend to expose only
retrieval operations over HTTP, and perform other interactions via non-HTTP protocols.
<span class="rfc2119-assertion" id="tdd-reg-read-only-auth">
To expose read-only access, the directory MUST enforce access control
on create, update, and delete interfaces.</span>
mmccool marked this conversation as resolved.
Show resolved Hide resolved
</li>
<li>
<span class="rfc2119-assertion" id="tdd-reg-default-representation">
The default serialization format for all request and success response bodies MUST be
JSON, with JSON-LD 1.1 [[JSON-LD11]] syntax to support extensions and semantic
processing.</span>
</li>
<li>
<span class="rfc2119-assertion" id="tdd-reg-additional-representation">
Directories MAY accept additional representations based on request's indicated
Content-Type or Content-Encoding, and provide additional representations through
server-driven content negotiation.</span>
This is useful for applications that require serializations other than JSON.
</li>
</ul>
</p>

<p>
The CRUDL operations are described in the following sections:
</p>

<section id="exploration-directory-api-registration-creation" class="normative">
<h4>Creation</h4>
<p>
<span class="rfc2119-assertion" id="tdd-reg-create-body">
The API MUST allow registration of a TD object passed as request body.
</span>
<span class="rfc2119-assertion" id="tdd-reg-create-contenttype">
The request SHOULD contain `application/td+json` Content-Type header for
JSON serialization of TD.
</span>
Creation refers to the registration of a new <a>TD</a> inside the directory.
</p>
<p>
The TD object is validated in accordance with [[[#validation]]].
Note that a TD may or may not be generated by the <a>Thing</a> it describes.
For brownfield devices in particular a separate <a>Discoverer</a> process
Expand All @@ -927,9 +982,16 @@ <h4>Creation</h4>
<ul>
<li>
<span class="rfc2119-assertion" id="tdd-reg-create-known-td">
A TD MUST be submitted to the directory using an HTTP `PUT` request
at `/things/{id}` endpoint, where `id` is the unique TD identifier.
A TD that has an `id` MUST be submitted to the directory in the body of an HTTP `PUT` request
at `/things/{id}` endpoint, where `id` is the unique TD identifier,
present inside the TD object.
</span>
An <a>Anonymous TD</a> is handled differently; see below.
<span class="rfc2119-assertion" id="tdd-reg-create-known-contenttype">
The request SHOULD contain `application/td+json` Content-Type header for
JSON serialization of TD.
</span>
The TD object is validated in accordance with [[[#validation]]].
<span class="rfc2119-assertion" id="tdd-reg-create-known-td-resp">
Upon successful processing, the server MUST respond with
201 (Created) status.
Expand All @@ -947,9 +1009,14 @@ <h4>Creation</h4>
</li>
<li>
<span class="rfc2119-assertion" id="tdd-reg-create-anonymous-td">
An <a>Anonymous TD</a> MUST be submitted to the directory using an HTTP `POST` request
at `/things` endpoint.
An <a>Anonymous TD</a> MUST be submitted to the directory in the body of
an HTTP `POST` request at `/things` endpoint.
</span>
<span class="rfc2119-assertion" id="tdd-reg-create-anonymous-contenttype">
The request SHOULD contain `application/td+json` Content-Type header for
JSON serialization of TD.
</span>
The TD object is validated in accordance with [[[#validation]]].
<span class="rfc2119-assertion" id="tdd-reg-create-anonymous-td-resp">
Upon successful processing, the server MUST respond with 201 (Created) status
and a Location header containing a system-generated identifier for the TD.
Expand All @@ -974,11 +1041,13 @@ <h4>Creation</h4>
Error responses:
<ul>
<li>
400 (Bad Request): Invalid serialization or TD.
400 (Bad Request): Bad user input such as
invalid serialization, invalid TD, `id` mismatch.
mmccool marked this conversation as resolved.
Show resolved Hide resolved
This is accompanied by an appropriate response message.
</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>

Expand All @@ -990,7 +1059,7 @@ <h4>Creation</h4>
<h4>Retrieval</h4>
<p>
<span class="rfc2119-assertion" id="tdd-reg-retrieve">
The API MUST allow retrieval of an existing TD using an HTTP `GET` request
The retrieval of an existing TD MUST be done using an HTTP `GET` request
at `/things/{id}` endpoint, where `id` is the unique TD identifier.
</span>
<span class="rfc2119-assertion" id="tdd-reg-retrieve-resp">
Expand All @@ -1009,6 +1078,7 @@ <h4>Retrieval</h4>
<li>404 (Not Found): TD with the given `id` not found.</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>

Expand Down Expand Up @@ -1116,9 +1186,9 @@ <h4>Retrieval</h4>
<section id="exploration-directory-api-registration-update" class="normative">
<h4>Update</h4>
<p>
<span class="rfc2119-assertion" id="tdd-reg-update-types">
The API MUST allow modifications to an existing TD as full replacement or partial updates.
</span>
The update operations are to replace or partially modify an existing TD.
</p>
<p>
The update operations are described below:
</p>

Expand Down Expand Up @@ -1228,6 +1298,7 @@ <h4>Update</h4>
<li>404 (Not Found): TD with the given `id` not found (for `PATCH` only).</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>
</section>
Expand All @@ -1236,7 +1307,7 @@ <h4>Update</h4>
<h4>Deletion</h4>
<p>
<span class="rfc2119-assertion" id="tdd-reg-delete">
A TD MUST be removed from the directory when an HTTP `DELETE` request is submitted
A delete operation MUST be done using an HTTP `DELETE` request is submitted
mmccool marked this conversation as resolved.
Show resolved Hide resolved
at `/things/{id}`, where `id` is the identifier of the existing TD.
</span>
<span class="rfc2119-assertion" id="tdd-reg-delete-resp">
Expand All @@ -1252,6 +1323,7 @@ <h4>Deletion</h4>
<li>404 (Not Found): TD with the given `id` not found.</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>
</section>
Expand Down Expand Up @@ -1465,6 +1537,9 @@ <h4>Listing</h4>
<ul>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>501 (Not Implemented): Requested feature not implemented,
such as custom sorting.
</li>
</ul>
</p>

Expand Down Expand Up @@ -1537,7 +1612,7 @@ <h4>Validation</h4>

</section>
<section id="exploration-directory-api-management" class="normative">
<h4>Management</h4>
<h4>Management API</h4>
<p class="ednote" title="Management API">
To do: Other administrative functions not having to do with CRUD of individual records,
for example, security configuration.
Expand All @@ -1546,7 +1621,7 @@ <h4>Management</h4>
</p>
</section>
farshidtz marked this conversation as resolved.
Show resolved Hide resolved
<section id="exploration-directory-api-notification" class="normative">
<h4>Notification</h4>
<h4>Events API</h4>
<p>
The Notification API is to notify clients about the changes
to <a>TDs</a> maintained within the directory.
Expand Down Expand Up @@ -1749,7 +1824,7 @@ <h4>Notification</h4>

</section>
<section id="exploration-directory-api-search" class="normative">
<h4>Search</h4>
<h4>Search API</h4>

<p class="ednote" title="Search API Overview">
Sub-API to search a directory, e.g. issue a query.
Expand Down Expand Up @@ -1805,6 +1880,7 @@ <h4>Syntactic search: JSONPath</h4>
<li>400 (Bad Request): JSONPath expression not provided or contains syntax errors.</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>
</section>
Expand All @@ -1827,6 +1903,7 @@ <h4>Syntactic search: XPath</h4>
<li>400 (Bad Request): XPath expression not provided or contains syntax errors.</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>
</section>
Expand Down Expand Up @@ -1861,7 +1938,7 @@ <h4>Semantic search: SPARQL</h4>
<li>400 (Bad Request): SPARQL query not provided or contains syntax errors.</li>
<li>401 (Unauthorized): No authentication.</li>
<li>403 (Forbidden): Insufficient rights to the resource.</li>
<li>501 (Not Implemented): SPARQL API not supported.</li>
<li>404 (Not Found): Endpoint not provided.</li>
</ul>
</p>
<span class="rfc2119-assertion" id="tdd-search-sparql-federation">
Expand Down Expand Up @@ -2167,7 +2244,7 @@ <h2>Incremental Transfer</h2>
</section>

<section id="directory-api-spec">
<h1>Directory Service API Specification</h1>
<h1>Directory Service API Specification (Thing Model)</h1>

<p class="issue" data-number="86">
To do: add a
Expand All @@ -2179,7 +2256,9 @@ <h1>Directory Service API Specification</h1>
The <a>TM</a> should describe all interaction affordances and indicate which ones
are required (i.e. mandatory by this spec). Moreover, it should use placeholders
for deployment-specific attributes.
Informative affordances (JSONPath and XPath) should be defined as such.
mmccool marked this conversation as resolved.
Show resolved Hide resolved
</p>

The API of the directory is specified as a <a>Thing Model</a>.
The Thing Model alone should not be considered as the reference
to implement or interact with a directory.
mmccool marked this conversation as resolved.
Show resolved Hide resolved
Expand Down