Skip to content

Commit

Permalink
Merge pull request #271 from ember-nexus/github-issue/233
Browse files Browse the repository at this point in the history
GitHub issue/233
  • Loading branch information
Syndesi authored Mar 10, 2024
2 parents 8ff471b + 11b52ec commit b8eb7cc
Show file tree
Hide file tree
Showing 54 changed files with 1,672 additions and 76 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- Add support for the `If-Match`-header, closes #232.
- Add support for the `If-None-Match`-header, closes #233.
- Add links in error endpoints to http.dev explaining the current error status code, closes #267.
- Add documentation for the GET `error/500/internal-server-error` endpoint, closes #251.
### Changed
- Increase reference dataset version to 0.0.24.
- Refactor parts of the Etag generation in order to make implementation of #232 and #233 easier.
### Fixed
- Fix controller example tests for put element and patch element endpoints, uncovered in #233.

## 0.1.3 - 2024-03-04
### Changed
Expand Down
12 changes: 12 additions & 0 deletions docs/api-endpoints/element/delete-element.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ element.

[Response Body](./delete-element/404-response-body.json ':include :type=code problem+json')

### **🔴 Error 412**

Error 412 is thrown if the request header `If-Match` or `If-None-Match` is present and their precondition fails.

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./delete-element/412-response-header.txt ':include :type=code')

<div class="code-title auto-refresh">Response Body</div>

[Response Body](./delete-element/412-response-body.json ':include :type=code problem+json')

### **🔴 Error 429**

<div class="code-title">Response Headers</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "http://ember-nexus-api/error/412/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "Precondition does not match."
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Content-Type: application/problem+json; charset=utf-8
Date: Mon, 09 Oct 2023 21:22:17 GMT
Date: Fri, 08 Mar 2024 21:34:53 GMT
Server: Unit
Transfer-Encoding: chunked
X-Powered-By: Ember Nexus API
31 changes: 29 additions & 2 deletions docs/api-endpoints/element/get-children.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ curl \

[Response Body](./get-children/200-response-body.json ':include :type=code')

### **🟢 Redirect 304**

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./get-children/304-response-header.txt ':include :type=code')

Redirect response does not have a response body.

### **🔴 Error 401**

This error can only be thrown if the token is invalid or if there is no default anonymous user.
Expand All @@ -80,6 +88,18 @@ This error can only be thrown if the token is invalid or if there is no default

[Response Body](./get-element/404-response-body.json ':include :type=code problem+json')

### **🔴 Error 412**

Error 412 is thrown if the request header `If-Match` or `If-None-Match` is present and their precondition fails.

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./delete-element/412-response-header.txt ':include :type=code')

<div class="code-title auto-refresh">Response Body</div>

[Response Body](./delete-element/412-response-body.json ':include :type=code problem+json')

### **🔴 Error 429**

<div class="code-title">Response Headers</div>
Expand All @@ -98,7 +118,7 @@ This error can only be thrown if the token is invalid or if there is no default

Once the server receives such a request, it checks several things internally:

<div id="graph-container-1" class="graph-container" style="height:1400px"></div>
<div id="graph-container-1" class="graph-container" style="height:1700px"></div>

<!-- panels:end -->

Expand Down Expand Up @@ -153,13 +173,16 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ id: 'noTokenAction', ...workflowStep, label: "use default anonymous\nuser for auth" },
{ id: 'checkTokenValidity', ...workflowDecision, label: 'is token valid?' },
{ id: 'checkRateLimit', ...workflowDecision, label: "does request exceed\nrate limit?" },
{ id: 'checkIfNoneMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-None-Match header?" },
{ id: 'checkIfNoneMatchHeaderMatches', ...workflowDecision, label: "does If-None-Match\nmatch ETag?" },
{ id: 'checkIfMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-Match header?" },
{ id: 'checkIfMatchHeaderMatches', ...workflowDecision, label: "does If-Match\nmatch ETag?" },
{ id: 'checkElementExistence', ...workflowDecision, label: "does element exist?" },
{ id: 'checkRelation', ...workflowDecision, label: "is element relation?" },
{ id: 'checkAccess', ...workflowDecision, label: "has user access?" },
{ id: 'loadElementsData', ...workflowStep, label: 'load children' },
{ id: 'success200', ...workflowEndSuccess , label: "return 200"},
{ id: 'redirect304', ...workflowEndSuccess , label: "return 304"},
{ id: 'error401', ...workflowEndError, label: "return 401" },
{ id: 'error404', ...workflowEndError, label: "return 404" },
{ id: 'error412', ...workflowEndError, label: 'return 412' },
Expand All @@ -171,8 +194,12 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ source: 'checkToken', target: 'checkTokenValidity', label: 'yes' },
{ source: 'checkTokenValidity', target: 'checkRateLimit', label: 'yes' },
{ source: 'checkTokenValidity', target: 'error401', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfNoneMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'error429', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfNoneMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'redirect304', label: 'yes' },
{ source: 'checkIfMatchHeaderExists', target: 'checkElementExistence', label: 'no' },
{ source: 'checkIfMatchHeaderExists', target: 'checkIfMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfMatchHeaderMatches', target: 'checkElementExistence', label: 'yes' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method
Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Date: Sun, 10 Mar 2024 13:46:31 GMT
ETag: "TMfc6KdsY3a"
Server: Unit
X-Powered-By: Ember Nexus API
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "http://ember-nexus-api/error/412/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "Precondition does not match."
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Content-Type: application/problem+json; charset=utf-8
Date: Mon, 09 Oct 2023 21:22:17 GMT
Date: Fri, 08 Mar 2024 21:34:53 GMT
Server: Unit
Transfer-Encoding: chunked
X-Powered-By: Ember Nexus API
31 changes: 29 additions & 2 deletions docs/api-endpoints/element/get-element.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ curl \

[Response Body](./get-element/200-relation-response-body.json ':include :type=code')

### **🟢 Redirect 304**

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./get-element/304-response-header.txt ':include :type=code')

Redirect response does not have a response body.

### **🔴 Error 401**

<div class="code-title auto-refresh">Response Headers</div>
Expand All @@ -81,6 +89,18 @@ curl \

[Response Body](./get-element/404-response-body.json ':include :type=code problem+json')

### **🔴 Error 412**

Error 412 is thrown if the request header `If-Match` or `If-None-Match` is present and their precondition fails.

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./delete-element/412-response-header.txt ':include :type=code')

<div class="code-title auto-refresh">Response Body</div>

[Response Body](./delete-element/412-response-body.json ':include :type=code problem+json')

### **🔴 Error 429**

<div class="code-title">Response Headers</div>
Expand All @@ -99,7 +119,7 @@ curl \

Once the server receives such a request, it checks several things internally:

<div id="graph-container-1" class="graph-container" style="height:1200px"></div>
<div id="graph-container-1" class="graph-container" style="height:1500px"></div>

<!-- panels:end -->

Expand Down Expand Up @@ -154,12 +174,15 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ id: 'noTokenAction', ...workflowStep, label: "use default anonymous\nuser for auth" },
{ id: 'checkTokenValidity', ...workflowDecision, label: 'is token valid?' },
{ id: 'checkRateLimit', ...workflowDecision, label: "does request exceed\nrate limit?" },
{ id: 'checkIfNoneMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-None-Match header?" },
{ id: 'checkIfNoneMatchHeaderMatches', ...workflowDecision, label: "does If-None-Match\nmatch ETag?" },
{ id: 'checkIfMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-Match header?" },
{ id: 'checkIfMatchHeaderMatches', ...workflowDecision, label: "does If-Match\nmatch ETag?" },
{ id: 'checkElementExistence', ...workflowDecision, label: 'does element exist?' },
{ id: 'checkElementAccess', ...workflowDecision, label: "does user has\naccess to element?" },
{ id: 'loadElementData', ...workflowStep, label: 'Load element data' },
{ id: 'success200', ...workflowEndSuccess , label: "return 200"},
{ id: 'redirect304', ...workflowEndSuccess , label: "return 304"},
{ id: 'error401', ...workflowEndError, label: "return 401" },
{ id: 'error404', ...workflowEndError, label: 'return 404' },
{ id: 'error412', ...workflowEndError, label: 'return 412' },
Expand All @@ -171,8 +194,12 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ source: 'checkToken', target: 'checkTokenValidity', label: 'yes' },
{ source: 'checkTokenValidity', target: 'checkRateLimit', label: 'yes' },
{ source: 'checkTokenValidity', target: 'error401', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfNoneMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'error429', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfNoneMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'redirect304', label: 'yes' },
{ source: 'checkIfMatchHeaderExists', target: 'checkElementExistence', label: 'no' },
{ source: 'checkIfMatchHeaderExists', target: 'checkIfMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfMatchHeaderMatches', target: 'checkElementExistence', label: 'yes' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method
Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Date: Sun, 10 Mar 2024 13:46:31 GMT
ETag: "TMfc6KdsY3a"
Server: Unit
X-Powered-By: Ember Nexus API
6 changes: 6 additions & 0 deletions docs/api-endpoints/element/get-element/412-response-body.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "http://ember-nexus-api/error/412/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "Precondition does not match."
}
10 changes: 10 additions & 0 deletions docs/api-endpoints/element/get-element/412-response-header.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method
Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Content-Type: application/problem+json; charset=utf-8
Date: Fri, 08 Mar 2024 21:34:53 GMT
Server: Unit
Transfer-Encoding: chunked
X-Powered-By: Ember Nexus API
31 changes: 29 additions & 2 deletions docs/api-endpoints/element/get-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ curl \

[Response Body](./get-index/200-response-body.json ':include :type=code')

### **🟢 Redirect 304**

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./get-index/304-response-header.txt ':include :type=code')

Redirect response does not have a response body.

### **🔴 Error 401**

This error can only be thrown if the token is invalid or if there is no default anonymous user.
Expand All @@ -70,6 +78,18 @@ This error can only be thrown if the token is invalid or if there is no default

[Response Body](./get-index/401-response-body.json ':include :type=code problem+json')

### **🔴 Error 412**

Error 412 is thrown if the request header `If-Match` or `If-None-Match` is present and their precondition fails.

<div class="code-title auto-refresh">Response Headers</div>

[Response Body](./delete-element/412-response-header.txt ':include :type=code')

<div class="code-title auto-refresh">Response Body</div>

[Response Body](./delete-element/412-response-body.json ':include :type=code problem+json')

### **🔴 Error 429**

<div class="code-title">Response Headers</div>
Expand All @@ -88,7 +108,7 @@ This error can only be thrown if the token is invalid or if there is no default

Once the server receives such a request, it checks several things internally:

<div id="graph-container-1" class="graph-container" style="height:1200px"></div>
<div id="graph-container-1" class="graph-container" style="height:1500px"></div>

<!-- panels:end -->

Expand Down Expand Up @@ -143,10 +163,13 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ id: 'noTokenAction', ...workflowStep, label: "use default anonymous\nuser for auth" },
{ id: 'checkTokenValidity', ...workflowDecision, label: 'is token valid?' },
{ id: 'checkRateLimit', ...workflowDecision, label: "does request exceed\nrate limit?" },
{ id: 'checkIfNoneMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-None-Match header?" },
{ id: 'checkIfNoneMatchHeaderMatches', ...workflowDecision, label: "does If-None-Match\nmatch ETag?" },
{ id: 'checkIfMatchHeaderExists', ...workflowDecision, label: "does request contain\nIf-Match header?" },
{ id: 'checkIfMatchHeaderMatches', ...workflowDecision, label: "does If-Match\nmatch ETag?" },
{ id: 'loadElementsData', ...workflowStep, label: 'Load root level elements' },
{ id: 'success200', ...workflowEndSuccess , label: "return 200"},
{ id: 'redirect304', ...workflowEndSuccess , label: "return 304"},
{ id: 'error401', ...workflowEndError, label: "return 401" },
{ id: 'error412', ...workflowEndError, label: 'return 412' },
{ id: 'error429', ...workflowEndError, label: 'return 429' },
Expand All @@ -157,8 +180,12 @@ renderWorkflow(document.getElementById('graph-container-1'), {
{ source: 'checkToken', target: 'checkTokenValidity', label: 'yes' },
{ source: 'checkTokenValidity', target: 'checkRateLimit', label: 'yes' },
{ source: 'checkTokenValidity', target: 'error401', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'checkIfNoneMatchHeaderExists', label: 'no' },
{ source: 'checkRateLimit', target: 'error429', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderExists', target: 'checkIfNoneMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'checkIfMatchHeaderExists', label: 'no' },
{ source: 'checkIfNoneMatchHeaderMatches', target: 'redirect304', label: 'yes' },
{ source: 'checkIfMatchHeaderExists', target: 'loadElementsData', label: 'no' },
{ source: 'checkIfMatchHeaderExists', target: 'checkIfMatchHeaderMatches', label: 'yes' },
{ source: 'checkIfMatchHeaderMatches', target: 'loadElementsData', label: 'yes' },
Expand Down
9 changes: 9 additions & 0 deletions docs/api-endpoints/element/get-index/304-response-header.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method
Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Date: Sun, 10 Mar 2024 13:46:31 GMT
ETag: "TMfc6KdsY3a"
Server: Unit
X-Powered-By: Ember Nexus API
6 changes: 6 additions & 0 deletions docs/api-endpoints/element/get-index/412-response-body.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "http://ember-nexus-api/error/412/precondition-failed",
"title": "Precondition Failed",
"status": 412,
"detail": "Precondition does not match."
}
10 changes: 10 additions & 0 deletions docs/api-endpoints/element/get-index/412-response-header.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method
Access-Control-Allow-Methods: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK
Cache-Control: no-cache, private
Content-Type: application/problem+json; charset=utf-8
Date: Fri, 08 Mar 2024 21:34:53 GMT
Server: Unit
Transfer-Encoding: chunked
X-Powered-By: Ember Nexus API
Loading

0 comments on commit b8eb7cc

Please sign in to comment.