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

Migrate to mkdocs #94

Merged
merged 14 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
17 changes: 17 additions & 0 deletions .github/md_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"aliveStatusCodes": [429, 200, 520],
"ignorePatterns": [
{
"pattern": "^(https://stakater).+"
},
{
"pattern": "^(http://nexus).+"
},
{
"pattern": "^(https://nexus).+"
},
{
"pattern": "^(https://docs.github.com).+"
}
]
}
6 changes: 6 additions & 0 deletions .github/workflows/pull_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
- 'master'

jobs:
qa:
uses: stakater/.github/.github/workflows/[email protected]
with:
MD_CONFIG: .github/md_config.json
DOC_SRC: content
MD_LINT_CONFIG: .markdownlint.yaml
build:
uses: stakater/.github/.github/workflows/[email protected]
with:
Expand Down
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ node_modules/
.vuepress/dist/
.DS_Store
.vscode
.idea
.idea

site/
styles/
mkdocs.yml
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "theme_common"]
path = theme_common
url = [email protected]:stakater/stakater-docs-mkdocs-theme.git
8 changes: 8 additions & 0 deletions .markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"MD007": { "indent": 4 },
"MD013": false,
"MD024": false,
"MD029": { "style": one },
"MD033": false,
"MD046": false,
}
10 changes: 10 additions & 0 deletions .vale.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
StylesPath = styles
MinAlertLevel = warning

Packages = https://github.com/stakater/vale-package/releases/download/v0.0.21/Stakater.zip
Vocab = Stakater

# Only check MarkDown files
[*.md]

BasedOnStyles = Vale
38 changes: 17 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
FROM registry.access.redhat.com/ubi8/nodejs-12
FROM python:3.12 as builder

LABEL name="Stakater Developer Handbook" \
maintainer="Stakater <[email protected]>" \
vendor="Stakater" \
release="1" \
summary="Developer Handbook"
RUN pip3 install mkdocs-mermaid2-plugin mkdocs-table-reader-plugin mkdocs-include-markdown-plugin

# set workdir
RUN mkdir -p $HOME/application
Expand All @@ -13,22 +9,22 @@ WORKDIR $HOME/application
# copy the entire application
COPY --chown=1001:root . .

# install yarn globaly
RUN npm install -g yarn

# download the application dependencies
RUN yarn install

# build the application
RUN yarn run build

# Change ownership of cache to make it writable
RUN chown -R 1001 ~/.cache

# Change permissions to fix EACCESS permission error
RUN chmod -R 755 $HOME
# build the docs
RUN chmod +x prepare_theme.sh && ./prepare_theme.sh
RUN mkdocs build
FROM nginxinc/nginx-unprivileged:1.26-alpine as deploy
COPY --from=builder $HOME/application/site/ /usr/share/nginx/html/
COPY default.conf /etc/nginx/conf.d/

# set non-root user
USER 1001

ENTRYPOINT ["yarn", "run", "serve"]
LABEL name="Stakater Developer Handbook" \
maintainer="Stakater <[email protected]>" \
vendor="Stakater" \
release="1" \
summary="Developer Handbook"

EXPOSE 8080:8080/tcp

CMD ["nginx", "-g", "daemon off;"]
22 changes: 1 addition & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1 @@
# developer-handbook

Local development

## MacOS

All dependencies for the developer handbook is handled with yarn.

```bash
# install nodejs with brew
brew install node

# install yarn with npm
npm install -g yarn

# install dependencies with yarn
yarn

# start local development server
yarn run dev
```
# Developer Handbook
13 changes: 6 additions & 7 deletions content/api/foundations.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The Foundations section outlines the design principles upon which the rest of th

## Provide Request-Ids for Introspection

Include a `Request-Id` header in each API response, populated with a UUID value. By logging these values on the client, server and any backing services, it provides a mechanism to trace, diagnose and debug requests.
Include a `Request-Id` header in each API response, populated with a uuid value. By logging these values on the client, server and any backing services, it provides a mechanism to trace, diagnose and debug requests.
karl-johan-grahn marked this conversation as resolved.
Show resolved Hide resolved

## Divide Large Responses Across Requests with Ranges

Expand All @@ -14,7 +14,7 @@ to specify when more data is available and how to retrieve it. See the
for the details of request and response headers, status codes, limits,
ordering, and iteration.

# Require Secure Connections
## Require Secure Connections

Require secure connections with TLS to access the API, without exception.
It’s not worth trying to figure out or explain when it is OK to use TLS
Expand All @@ -25,10 +25,10 @@ http or port 80 to avoid any insecure data exchange. In environments where this
is not possible, respond with `403 Forbidden`.

Redirects are discouraged since they allow sloppy/bad client behaviour without
providing any clear gain. Clients that rely on redirects double up on
providing any clear gain. Clients that rely on redirects double up on
server traffic and render TLS useless since sensitive data will already
have been exposed during the first call.

## Separate Concerns

Keep things simple while designing by separating the concerns between the
Expand All @@ -37,14 +37,13 @@ allows for greater focus on larger and harder problems.

Requests and responses will be made to address a particular resource or
collection. Use the path to indicate identity, the body to transfer the
contents and headers to communicate metadata. Query params may be used as a
contents and headers to communicate metadata. Query parameters may be used as a
means to pass header information also in edge cases, but headers are preferred
as they are more flexible and can convey more diverse information.

## Support ETags for Caching
## Support `ETags` for Caching

Include an `ETag` header in all responses, identifying the specific
version of the returned resource. This allows users to cache resources
and use requests with this value in the `If-None-Match` header to determine
if the cache should be updated.

4 changes: 2 additions & 2 deletions content/api/general-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ By defining APIs outside the code, we want to facilitate early review feedback a
Moreover, API definitions with standardized specification format also facilitate...

- single source of truth for the API specification; it is a crucial part of a contract between service provider and client users
- infrastructure tooling for API discovery, API GUIs, API documents, automated quality checks
- infrastructure tooling for API discovery, API GUI, API documents, automated quality checks

It is important to learn, that API First is not in conflict with the agile development principles that we love. Service applications should evolve incrementally — and so its APIs. Of course, API specification will and should evolve iteratively in different cycles, each starting with draft status and early team and peer review feedback.

Expand All @@ -32,4 +32,4 @@ We use the OpenAPI specification (aka Swagger spec) as standard for REST API def

We also call the OpenAPI API definition the "API Reference definition" (or "API definition"); it provides all information needed by an experienced API client developer to use this API.

The OpenAPI API specification file should be subject of version control together with source code management. Services also have to support an endpoint to access the API Reference definition for their external API(s).
The OpenAPI API specification file should be subject of version control together with source code management. Services also have to support an endpoint to access the API Reference definition for their external API(s).
9 changes: 4 additions & 5 deletions content/api/how-to-model-workflows-in-rest-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ RESTful Web Services are awesome for performing basic CRUD operations on databas
There are three options:

1. Use an Attribute for the Workflow’s State
2. Use Hyperlinks for Workflow Transitions
3. Use a Subresource for Workflow Transitions
1. Use Hyperlinks for Workflow Transitions
1. Use a `Subresource` for Workflow Transitions

## So which one should I pick?

Expand All @@ -18,11 +18,10 @@ As always, it depends on the context, but here are some quick guidelines:
| --- | --- |
| State Attribute | When there are no restrictions on the transitions. You can go from any state to any state at any time. The states are basically nothing more than a list of values. |
| Transition Links | There are limits to which states you can go to depending on the current state. |
| Transition Subresource | The workflow is configurable by users, so states and transitions among them are not fixed, but can be changed at runtime. |

| Transition `Subresource` | The workflow is configurable by users, so states and transitions among them are not fixed, but can be changed at runtime. |

## Reference

Read following for more details:

- https://www.kennethlange.com/how-to-model-workflows-in-rest-apis/
- [How to Model Workflows in REST APIs](https://www.kennethlange.com/how-to-model-workflows-in-rest-apis/)
67 changes: 34 additions & 33 deletions content/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,71 +16,71 @@ Note: GET requests on collection resources should provide a sufficient filter me

### POST

POST requests are idiomatically used to create single resources on a collection resource endpoint, but other semantics on
single resources endpoint are equally possible. The semantic for collection endpoints is best described as »please add the
enclosed representation to the collection resource identified by the URL«. The semantic for single resource endpoints is
POST requests are idiomatically used to create single resources on a collection resource endpoint, but other semantics on
single resources endpoint are equally possible. The semantic for collection endpoints is best described as »please add the
enclosed representation to the collection resource identified by the URL«. The semantic for single resource endpoints is
best described as »please execute the given well specified request on the collection resource identified by the URL«.

- POST request should only be applied to collection resources, and normally not on single resource, as this has an undefined
- POST request should only be applied to collection resources, and normally not on single resource, as this has an undefined
semantic
- on successful POST requests, the server will create one or multiple new resources and provide their URI/URLs in the
- on successful POST requests, the server will create one or multiple new resources and provide their URI/URLs in the
response
- successful POST requests will usually generate 200 (if resources have been updated), 201 (if resources have been created),
- successful POST requests will usually generate 200 (if resources have been updated), 201 (if resources have been created),
and 202 (if the request was accepted but has not been finished yet)

More generally: POST should be used for scenarios that cannot be covered by the other methods sufficiently. For instance,
GET with complex (e.g. SQL like structured) query that needs to be passed as request body payload because of the URL-length
More generally: POST should be used for scenarios that cannot be covered by the other methods sufficiently. For instance,
GET with complex (e.g. SQL like structured) query that needs to be passed as request body payload because of the URL-length
constraint. In such cases, make sure to document the fact that POST is used as a workaround.

Note: Resource IDs with respect to POST requests are created and maintained by server and returned with response payload.
Posting the same resource twice is by itself not required to be idempotent and may result in multiple resource instances.
Anyhow, if external URIs are present that can be used to identify duplicate requests, it is best practice to implement POST
Note: Resource IDs with respect to POST requests are created and maintained by server and returned with response payload.
Posting the same resource twice is by itself not required to be idempotent and may result in multiple resource instances.
Anyhow, if external URIs are present that can be used to identify duplicate requests, it is best practice to implement POST
in an idempotent way.

### PUT

PUT requests are used to update single resources or an entire collection resources. The semantic is best described as
PUT requests are used to update single resources or an entire collection resources. The semantic is best described as
»please put the enclosed representation at the resource mentioned by the URL«.

- PUT requests are usually applied to single resources, and not to collection resources, as this would imply replacing the
- PUT requests are usually applied to single resources, and not to collection resources, as this would imply replacing the
entire collection
- PUT requests are usually robust against non-existence of resources by implicitly creating before updating
- on successful PUT requests, the server will replace the entire resource addressed by the URL with the representation
- on successful PUT requests, the server will replace the entire resource addressed by the URL with the representation
passed in the payload
- successful PUT requests will usually generate 200 or 204 (if the resource was updated - with or without actual content
- successful PUT requests will usually generate 200 or 204 (if the resource was updated - with or without actual content
returned), and 201 (if the resource was created)

Note: Resource IDs with respect to PUT requests are maintained by the client and passed as a URL path segment. Putting the
same resource twice is required to be idempotent and to result in the same single resource instance. If PUT is applied for
Note: Resource IDs with respect to PUT requests are maintained by the client and passed as a URL path segment. Putting the
same resource twice is required to be idempotent and to result in the same single resource instance. If PUT is applied for
karl-johan-grahn marked this conversation as resolved.
Show resolved Hide resolved
creating a resource, only URIs should be allowed as resource IDs. If URIs are not available POST should be preferred.

### PATCH

PATCH request are only used for partial update of single resources, i.e. where only a specific subset of resource fields
should be replaced. The semantic is best described as »please change the resource identified by the URL according to my
change request«. The semantic of the change request is not defined in the HTTP standard and must be described in the API
PATCH request are only used for partial update of single resources, i.e. where only a specific subset of resource fields
karl-johan-grahn marked this conversation as resolved.
Show resolved Hide resolved
should be replaced. The semantic is best described as »please change the resource identified by the URL according to my
change request«. The semantic of the change request is not defined in the HTTP standard and must be described in the API
specification by using suitable media types.

- PATCH requests are usually applied to single resources, and not on collection resources, as this would imply patching on
- PATCH requests are usually applied to single resources, and not on collection resources, as this would imply patching on
the entire collection
- PATCH requests are usually not robust against non-existence of resource instances
- on successful PATCH requests, the server will update parts of the resource addressed by the URL as defined by the change
- on successful PATCH requests, the server will update parts of the resource addressed by the URL as defined by the change
request in the payload
- successful PATCH requests will usually generate 200 or 204 (if resources have been updated with or without updated content
- successful PATCH requests will usually generate 200 or 204 (if resources have been updated with or without updated content
returned)

Note: since implementing PATCH correctly is a bit tricky, we strongly suggest to choose one and only one of the following patterns per endpoint, unless forced by a backwards compatible change. In preference order:

1. use PUT with complete objects to update a resource as long as feasible (i.e. do not use PATCH at all).
2. use PATCH with partial objects to only update parts of a resource, when ever possible. (This is basically [JSON Merge Patch](https://tools.ietf.org/html/rfc7396),
a specialized media type application/merge-patch+json that is a partial resource representation.)
3. use PATCH with [JSON Patch](http://tools.ietf.org/html/rfc6902), a specialized media type application/json-patch+json that
1. use PATCH with partial objects to only update parts of a resource, when ever possible. (This is basically [JSON Merge Patch](https://tools.ietf.org/html/rfc7396),
a specialized media type `application/merge-patch+json` that is a partial resource representation.)
1. use PATCH with [JSON Patch](http://tools.ietf.org/html/rfc6902), a specialized media type `application/json-patch+json` that
includes instructions on how to change the resource.
4. use POST (with a proper description of what is happening) instead of PATCH if the request does not modify the resource in
1. use POST (with a proper description of what is happening) instead of PATCH if the request does not modify the resource in
a way defined by the semantics of the media type.

In practice JSON Merge Patch quickly turns out to be too limited, especially when trying to update single objects in large
collections (as part of the resource). In this cases JSON Patch can shown its full power while still showing readable patch
In practice JSON Merge Patch quickly turns out to be too limited, especially when trying to update single objects in large
collections (as part of the resource). In this cases JSON Patch can shown its full power while still showing readable patch
karl-johan-grahn marked this conversation as resolved.
Show resolved Hide resolved
requests ([see also](http://erosb.github.io/post/json-patch-vs-merge-patch)).

### DELETE
Expand All @@ -105,16 +105,17 @@ OPTIONS are used to inspect the available operations (HTTP methods) of a given e

Note: OPTIONS is rarely implemented, though it could be used to self-describe the full functionality of a resource.

## Must: Fulfill Safeness and Idempotency Properties
## Must: Fulfill Safeness and Idempotent Properties

An operation can be...
An operation can be:

- idempotent, i.e. operation will produce the same results if executed once or multiple times (note: this does not necessarily mean returning the same status code)
- safe, i.e. must not have side effects such as state changes

Method implementations must fulfill the following basic properties:

| HTTP method | safe | idempotent |
```txt
| HTTP method | safe | idempotent |
| ------------- | ------------- | ------------- |
| OPTIONS | YES | YES |
| HEAD | YES | YES |
Expand All @@ -123,4 +124,4 @@ Method implementations must fulfill the following basic properties:
| POST | NO | NO |
| DELETE | NO | YES |
| PATCH | NO | NO |

```
Loading
Loading