Skip to content

Commit

Permalink
Merge pull request #1 from otto-de/initial_version
Browse files Browse the repository at this point in the history
Initial version
  • Loading branch information
manuelruhe authored Feb 13, 2023
2 parents 3df79b3 + 2aed5b6 commit 0bc4310
Show file tree
Hide file tree
Showing 184 changed files with 5,005 additions and 1 deletion.
30 changes: 30 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: convert

on:
push:
tags:
- 'v*'


jobs:
buildrelease:
name: Build and release artefacts
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Convert MD to PDF and HTML
run: |-
npm install -g md-to-pdf
mkdir -p _output
find . -name "*.md" ! -name "README.md" ! -name "CONTRIBUTING.md" ! -path "./_output/*" | sort -n | while read file; do cat "$file"; echo "<div class="page-break"></div>"; echo; done > ./_output/otto-retail-api-guidelines.md
md-to-pdf ./_output/otto-retail-api-guidelines.md
md-to-pdf --as-html --config-file ./.github/workflows/config.json ./_output/otto-retail-api-guidelines.md
- name: Release
uses: softprops/action-gh-release@v1
with:
files: |
./_output/otto-retail-api-guidelines.html
./_output/otto-retail-api-guidelines.pdf
3 changes: 3 additions & 0 deletions .github/workflows/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"css": "body { margin: 15px}"
}
16 changes: 16 additions & 0 deletions 01_getting-started/01_introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# OTTO RETAIL-API - Getting Started

## Introduction
The OTTO Retail-API uses standard [HTTP semantics](https://httpwg.org/http-core/draft-ietf-httpbis-semantics-latest.html) as well as OAuth 2.0 for authentication and authorization and returns [JSON-encoded](http://www.json.org/) responses.
We support secure communication and require client applications to implement TLS 1.2 or higher.

With this [endpoint](https://keycloak.apps.otto.de/sec-api/auth/realms/retailapi-prod/.well-known/openid-configuration) for [OAuth 2.0 endpoint discovery](https://tools.ietf.org/html/draft-ietf-oauth-discovery-06)
you can use the returned information to obtain details about the OAuth 2.0 authorization server, such as endpoints for token and user information, as well as the supported OAuth 2.0 flows.

The OTTO Retail-API sandbox environment allows API testing without affecting or interacting with your live data.
The base URL for your requests determines whether the request is executed in the production or sandbox environment.
The following base URLs are available for all resources:

* Production base URL: https://retail-api.otto.de
* Sandbox environment base URL: https://retail-api-sandbox.otto.de

119 changes: 119 additions & 0 deletions 01_getting-started/02_authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
## Authentication

The OTTO Retail-API uses OAuth 2.0 for authentication and authorization on all endpoints and does not handle unauthenticated requests.
We only support the OAuth 2.0 flow **Client Credentials Grant**.

In order to make requests to the OTTO Retail-API, you first need to obtain an access token for your application.

As proposed in the [RFC 9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://datatracker.ietf.org/doc/html/rfc9068), the access tokens used for the OTTO Retail-API are JWTs, as defined in [RFC 7797](https://tools.ietf.org/html/rfc7797).


> :warning:
The grant flow Client Credentials require your client secret.
Make sure that your client secret is not included in your distributed code, compiled apps, or public JavaScript.

The OTTO Retail-API provides the following token endpoints:

| Endpoint | Description |
|------------------------------------------------------------------------------------------------| ---------------------------------------------- |
| https://keycloak.apps.otto.de/sec-api/auth/realms/retailapi-prod/protocol/openid-connect/token | Endpoint for token retrieval. |
| https://keycloak.apps.otto.de/sec-api/auth/realms/retailapi-prod/protocol/openid-connect/auth | Endpoint for authentication and authorization. |

Although you can expect that the tokens have the TTL (time to live) described below, we still recommend that you always check the actual expiry time by inspecting the `exp` claim of the JWT.

Access token TTL: 5 minutes

### Client Credentials Grant

With the Client Credentials Grant access token, your application receives direct access to all relevant resources that are not tied to specific users.
See [Client Credentials Grant](https://www.rfc-editor.org/rfc/rfc6749#section-4.4) for details.

#### Obtaining an access token

You receive an access token through a POST request containing your client ID and client secret in the request body.
Keep in mind that this information is set during the initial client registration process via the OTTO Supplier Connect.

The following table shows the required parameters for this request:

| Parameter | Description |
| ------------- | -------------------------------------------------------------------------- |
| grant_type | Use `client_credentials` for this request. |
| scope | A space-separated list of requested scopes. |
| client_id | Your client ID. Mandatory if you do not use HTTP basic authentication. |
| client_secret | Your client secret. Mandatory if you do not use HTTP basic authentication. |


Example request:

```http
POST https://keycloak.apps.otto.de/sec-api/auth/realms/retailapi-prod/protocol/openid-connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&scope=products orders
&client_id=<your_client_id>
&client_secret=<your_client_secret>
```

Example of a successful token response:

```http
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "<valid oauth2 access token>",
"token_type": "bearer",
"expires_in": 299,
"scope": "products orders",
"jti": "1e559445-21df-4f01-a9de-e55ab519b2c3"
}
```

Here's some info about the access token response properties:

| Property | Description |
|----------------|----------------------------------------------------------------------------------------------------------------|
| `access token` | Contains the access token, that you need to include in all further API requests in the `Authorization` header. |
| `token_type` | Identifies the type of the token. |
| `exp` | Specifies the timestamp after which the access token expires. |
| `scope` | Contains a space-separated list of all granted scopes. |
| `jti` | Contains a unique identifier of the access token. |


#### Making authorized requests

To make an authorized request to the OTTO Retail-API, add the `Authorization` header containing your access token to the HTTP request.
You can only access the resources with the scopes for which you initially registered your client.

Example request:

```http
GET /products/<productId> HTTP/1.1
Authorization: Bearer <valid oauth2 access token>
Accept: application/hal+json;profile="/product/product+v1"
```

If a request fails, the API returns an error response with an HTTP status code, and an error object with `error` and `error_description` parameters:

```http
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json
Cache-Control: no-store
{
"type": "about:blank",
"title": "Unauthorized",
"status": 401,
"detail": "Authentication is required, but has failed or has not yet been provided."
}
```

The API responds as follows:

| Response | Possible cause and solution |
|------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Code**: 401 UNAUTHORIZED | A possible cause might be a missing authorization header or incorrect credentials. |
| **Code**: 403 FORBIDDEN | Access to the requested resource is not allowed, because the access token is invalid or expired.<br>A possible solution is refreshing the access token. |

15 changes: 15 additions & 0 deletions 01_getting-started/03_scopes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Scopes

We protect access to our resources and restrict access to the OTTO Retail-API by using OAuth 2.0 scopes.
Scopes allow you to specify which permissions your client application requires.

Currently, all scopes are automatically assigned to your client with your initial request for API access.
Find more information on how to get API access [here](https://github.com/otto-de/retail-api-hub-documentation).

Here is an overview of all available business scopes:

**Production:**
- products

**Sandbox:**
- products-sandbox
21 changes: 21 additions & 0 deletions 02_about-the-api/01_api-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# About the API

## API operations

To build a REST request, combine the respective HTTP method with the following information:

- OTTO Retail-API base URL
- Resource URI with replaced path parameters
- Valid access token
- Request headers (operation-specific)
- Request body (operation-specific)

For example:

```http
POST /products/<product-id:string> HTTP/1.1
Host: https://retail-api.otto.de
Authorization: Bearer <access token>
Content-Type: application/hal+json;profile="/product/product+v1""
Accept: application/hal+json;profile="/product/product+v1""
```
12 changes: 12 additions & 0 deletions 02_about-the-api/02_http-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## HTTP methods

We are compliant with the standardized HTTP semantics and use the HTTP request methods `GET`, `POST`, `PUT`, `PATCH`, `DELETE` and `OPTIONS` throughout the API.

| Method | CRUD | Description |
| :-------: | :-------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET` | Read | Retrieve either a single or a collection resource. Successful `GET` requests return `200 OK`. For a collection resource, `GET` requests also return `200 OK` if the collection is empty. If a single or collection resource is missing, the API returns `404 Not Found` or `410 Gone`.<br>In case of a `404 Not Found`, check the structure of your query and the name of the requested endpoint and resource. |
| `POST` | Create | Create a single resource on a collection resource endpoint. Successful `POST` requests either return `200 OK` if the resource already exists, or `201 Created` if a new resource was created. In case of `201 Created` the `Location` header of the response contains the URI of the new resource. The request returns `202 Accepted` after it was accepted but not yet completed. In exceptional cases the request returns `204 No Content` with a `Location` header containing the URI of the new resource.<br>In error cases the request returns `422 Unprocessable Entity` for semantically malformed or `400 Bad Request` for syntactically malformed requests. |
| `PATCH` | Update/Modify | Update parts of a single resource. Successful `PATCH` requests return `200 OK` with a response body, or `204 No Content` if a resource was updated. |
| `PUT` | Update/Replace | Update or replace an entire resource. Successful `PUT` requests return `200 OK` with a response body. The request returns `201 Created` if the resource was created, or `204 No Content` if a resource was updated. |
| `DELETE` | Delete | Delete a resource. Successful `DELETE` requests usually return `204 No Content` without a response body. In rare cases, a delete request returns `200 OK`. Failed `DELETE` requests return `404 Not Found` if the resource cannot be found, or `410 Gone` if the resource has already been deleted before. |
| `OPTIONS` | Inspect Methods | Inspect the available HTTP methods of a given endpoint. `OPTIONS` responses usually contain either a comma-separated list of methods in the `Allow` header, or a structured list of link templates. |
Loading

0 comments on commit 0bc4310

Please sign in to comment.