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

docs(kopflos): handler pipeline #29

Merged
merged 8 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 7 additions & 0 deletions docs/apis/apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
sidebar_position: 1
---

# Data-Centric APIs

TBD - introduce the concept of data-centric APIs
2 changes: 2 additions & 0 deletions docs/apis/kopflos/_category_.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
label: Kopflos
position: 2
2 changes: 2 additions & 0 deletions docs/apis/kopflos/explanations/_category_.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
label: Explanations
position: 3
66 changes: 66 additions & 0 deletions docs/apis/kopflos/explanations/request-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Request pipeline
sidebar_position: 1
---

# Kopflos request pipeline

```
Incoming Request
└─▶ Kopflos handler
4**/5** ◀─┴─▶ Resource Shape Lookup
4**/5** ◀─┴─▶ Resource Loader Lookup
4**/5** ◀─┴─▶ Load Resource
4** ◀─┴─▶ Authorization
400 ◀─┴─▶ Validate payload
4**/5** ◀─┴─▶ Run handler
└─▶ Reply
```

## Incoming request

Incoming request is handled by the server library, such as express or fastify and then forwarded to Kopflos.

## Kopflos handler

Kopflos handler is the main entry point for all incoming requests. It is responsible for orchestrating the request pipeline.

## Resource Shape Lookup

Resource Shape Lookup executes SPARQL against the `default` query endpoint to find the shape targetting the requested resource.
tpluscode marked this conversation as resolved.
Show resolved Hide resolved

:::tip
See also: [How to Select which resources should be served by the API](../how-to/resource-shape.md)
:::

## Resource Loader Lookup + Load Resource

When the Resource Shape is found, a resource loader is selected based from `kopflos:resourceLoader` property, going bottom-up from the Resource/Property Shape to the share `kopflos:Config` resource.

It is used to load the requested resource's Core Representation.

:::info
The Core Representation are the triples returned by the resource loader. Typically, that would the result of a SPARQL `DESCRIBE` query or contents of resource's "own graph".
tpluscode marked this conversation as resolved.
Show resolved Hide resolved
:::

## Authorization

Not implemented yet.

## Validate payload

Not implemented yet.

## Run handler

Finally, the handler is executed. If no handler is defined, and the request method is a GET, the resource's Core Representation is returned.

The result of the handler is forwarded back to the server library to be sent as a response.
2 changes: 2 additions & 0 deletions docs/apis/kopflos/how-to/_category_.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
label: How-To
position: 2
71 changes: 71 additions & 0 deletions docs/apis/kopflos/how-to/resource-shape.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Select which resources should be served by the API

The central concept of the Kopflos is the `Resource Shape`. Its main purpose is to define which resources should be served by the API and how they should be served. Resource Shapes reuse some SHACL concepts.

## Serving all instances of a class

To have all instances of a class served by the API, define a shape that targets that class with `sh:targetClass`.

```turtle
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX kopflos: <https://kopflos.described.at/>
PREFIX ex: <http://example.org/>

<FooShape>
a kopflos:ResourceShape ;
sh:targetClass ex:Foo ;
.

<foo> a ex:Foo . # will be served by the API
<bar> a ex:Foo . # will be served by the API
<baz> a ex:Baz . # will not be served by the API
```

## Serving specific instances

To serve only specific instances of a class, define a shape that targets those instances with `sh:targetNode`.

```turtle
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX kopflos: <https://kopflos.described.at/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

<Shape>
a kopflos:ResourceShape ;
sh:targetNode <foo>, <bar> ;
.

<foo> rdfs:label "foo" . # will be served by the API
<bar> rdfs:label "bar" . # will be served by the API
<baz> rdfs:label "baz" . # will not be served by the API
```

## Serving objects of a property

In some scenarios, it is useful to assign a specific handler to objects of a resource property.

To do so, define a shape that targets the property with `sh:property/sh:path` and assign a `kopflos:handler` to that Property Shape.

```turtle
PREFIX ex: <http://example.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX kopflos: <https://kopflos.described.at/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

<fooShape>
a kopflos:ResourceShape ;
sh:targetClass ex:Foo ;
sh:property [
sh:path <foo#export> ;
kopflos:handler [
# ...
] ;
] ;
.

<foo>
a ex:Foo ;
<foo#export> <foo/export> ; # will be served by the API
<foo#import> <foo/import> ; # will not be served by the API
.
```
66 changes: 66 additions & 0 deletions docs/apis/kopflos/how-to/sparql-endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Configure SPARQL endpoints

Kopflos can be configured with one or more SPARQL endpoints which can be accessed at runtime by
handler implementors. A single endpoint is required, named `default`.

To configure the endpoints, one of three methods is supported.

## From endpoint URL

The simplest option is to provide a single unauthenticated endpoint URL which will be used for queries and updates.

```js
import Kopflos from '@kopflos-cms/core'

let graph

const kopflos = new Kopflos(graph, {
sparql: {
default: 'http://example.com/query',
}
})
```

## From endpoint configuration object

A more complex scenario will often require separate query and update URLs and authentication. In such
cases, provide a full settings object as required by [`sparql-http-client`](https://github.com/rdf-ext/sparql-http-client).

```js
import Kopflos from '@kopflos-cms/core'

let graph

const kopflos = new Kopflos(graph, {
sparql: {
default: {
endpointUrl
}
}
})
```

## Provide instances of SPARQL clients

Lastly, it is possible to create the clients manually in code and pass them to Kopflos.
Both `stream` and `parsed` clients are required.

```js
import StreamClient from 'sparql-http-client'
import ParsingClient from 'sparql-http-client/ParsingClient.js'
import Kopflos from '@kopflos-cms/core'

let graph

const stream = new SparqlClient({ endpointUrl })
const parsed = new ParsingClient({ endpointUrl })

const kopflos = new Kopflos(graph, {
sparql: {
default: {
stream,
parsed
}
}
})
```
2 changes: 1 addition & 1 deletion docs/cubes/cubes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ sidebar_position: 1

# RDF Data Cubes

This sections contains information about practical usage of RDF Data Cubes represented with the [cube.link Cube Schema](https://cube.link/).
This section contains information about practical usage of RDF Data Cubes represented with the [cube.link Cube Schema](https://cube.link/).
6 changes: 6 additions & 0 deletions docusaurus.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ const config = {
position: 'left',
label: 'Workflows',
},
{
type: 'docSidebar',
sidebarId: 'apisSidebar',
position: 'left',
label: 'APIs',
},
{
type: 'docSidebar',
sidebarId: 'cubesSidebar',
Expand Down
1 change: 1 addition & 0 deletions sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const sidebars = {
aboutSidebar: [{type: 'autogenerated', dirName: 'about'}],
rdfjsSidebar: [{type: 'autogenerated', dirName: 'rdfjs'}],
workflowsSidebar: [{type: 'autogenerated', dirName: 'workflows'}],
apisSidebar: [{type: 'autogenerated', dirName: 'apis'}],
cubesSidebar: [{type: 'autogenerated', dirName: 'cubes'}],

// But you can create a sidebar manually
Expand Down
10 changes: 10 additions & 0 deletions src/components/HomepageFeatures/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ const FeatureList: FeatureItem[] = [
</>
),
},
{
page: '/docs/apis/',
title: 'APIs',
image: '/img/kopflos.png',
description: (
<>
Simply create APIs for your data-centric applications
</>
),
},
{
page: '/docs/cubes/',
title: 'Cubes',
Expand Down
Binary file added static/img/kopflos.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading