Skip to content

Commit

Permalink
feat: configurable endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Jan 14, 2025
1 parent 8210a35 commit a819ad4
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 22 deletions.
1 change: 1 addition & 0 deletions example/kopflos.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default <KopflosConfig> {
updateUrl: 'http://localhost:7878/update',
storeUrl: 'http://localhost:7878/store',
},
lindas: 'https://lindas.admin.ch/query',
},
watch: ['lib'],
plugins: {
Expand Down
21 changes: 21 additions & 0 deletions example/resources/countries.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
PREFIX kl: <https://kopflos.described.at/>
PREFIX schema: <http://schema.org/>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX hydra: <http://www.w3.org/ns/hydra/core#>
prefix kl-hydra: <https://kopflos.described.at/hydra#>

<>
a hydra:Collection ;
hydra:memberAssertion
[
hydra:property rdf:type ;
hydra:object schema:Country ;
] ;
kl:endpoint "lindas" ;
kl-hydra:memberShape
[
sh:property [ sh:path schema:name ; sh:languageIn ("en" "de") ] ;
sh:property [ sh:path schema:identifier ] ;
] ;
.
30 changes: 16 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/ns.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import rdf from '@zazuko/env-node'

type Properties = 'api' | 'resourceLoader' | 'handler' | 'method' | 'config'
type Properties = 'api' | 'resourceLoader' | 'handler' | 'method' | 'config' | 'endpoint'
type Classes = 'Config' | 'Api' | 'ResourceShape' | 'Handler'
type Shorthands = 'DescribeLoader' | 'OwnGraphLoader'

Expand Down
11 changes: 9 additions & 2 deletions packages/hydra/handlers/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ constraints.set(kl['hydra#MemberAssertionConstraintComponent'], HydraMemberAsser

export function get(): Handler {
return ({ env, subject }) => {
const endpoint = subject.out(kl.endpoint).value || 'default'

if (!isReadable(env, subject)) {
return new error.MethodNotAllowed('Collection is not readable')
}

const memberQuery = constructQuery(memberQueryShape({ env, collection: subject }))
const members = env.sparql.default.stream.query.construct(memberQuery)
const sparqlClient = env.sparql[endpoint]
if (!sparqlClient) {
return new error.InternalServerError(`SPARQL endpoint '${endpoint}' not found`)
}

const members = sparqlClient.stream.query.construct(memberQuery)

const totalQuery = constructQuery(totalsQueryShape({ env, collection: subject }))
const totals = env.sparql.default.stream.query.construct(totalQuery)
const totals = sparqlClient.stream.query.construct(totalQuery)

return {
status: 200,
Expand Down
17 changes: 13 additions & 4 deletions packages/hydra/lib/queryShapes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ import { isGraphPointer } from 'is-graph-pointer'
// eslint-disable-next-line import/no-unresolved
import { kl } from '@kopflos-cms/core/ns.js'
import { log } from '@kopflos-cms/core'
import type { DatasetCoreFactory } from '@rdfjs/types'

interface MemberQueryShapeArgs {
env: Environment<ClownfaceFactory | NsBuildersFactory>
env: Environment<ClownfaceFactory | NsBuildersFactory | DatasetCoreFactory>
collection: GraphPointer
limit?: number
offset?: number
}

export function memberQueryShape({ env, collection, limit, offset }: MemberQueryShapeArgs): GraphPointer {
export function memberQueryShape({ env, collection: original, limit, offset }: MemberQueryShapeArgs): GraphPointer {
const { hydra, sh, rdf } = env.ns

const collection = env.clownface({
dataset: env.dataset([...original.dataset]),
term: original.term,
})
const shape = collection
.blankNode()
.addOut(rdf.type, sh.NodeShape)
Expand Down Expand Up @@ -105,13 +110,17 @@ export function memberQueryShape({ env, collection, limit, offset }: MemberQuery
}

interface TotalsQueryShapeArgs {
env: Environment<ClownfaceFactory | NsBuildersFactory>
env: Environment<ClownfaceFactory | NsBuildersFactory | DatasetCoreFactory>
collection: GraphPointer
}

export function totalsQueryShape({ env, collection }: TotalsQueryShapeArgs) {
export function totalsQueryShape({ env, collection: original }: TotalsQueryShapeArgs) {
const { hydra, sh, rdf } = env.ns

const collection = env.clownface({
dataset: env.dataset([...original.dataset]),
term: original.term,
})
const filterShape = collection.blankNode()
filterShape.addOut(hydra.memberAssertion, collection.out(hydra.memberAssertion))

Expand Down
2 changes: 1 addition & 1 deletion packages/hydra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"handlers/*.d.ts"
],
"dependencies": {
"@hydrofoil/shape-to-query": "^0.13.6",
"@hydrofoil/shape-to-query": "^0.13.8",
"@kopflos-cms/core": "^0.3.1",
"@sindresorhus/merge-streams": "^4.0.0",
"@tpluscode/rdf-ns-builders": "^4.3.0",
Expand Down
23 changes: 23 additions & 0 deletions packages/hydra/test/collection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('@kopflos-cms/hydra', () => {
baseIri,
sparql: {
default: inMemoryClients(this.rdf),
lindas: 'https://lindas.admin.ch/query',
},
}
})
Expand Down Expand Up @@ -136,6 +137,28 @@ describe('@kopflos-cms/hydra', () => {
expect(pointer.out(ns.hydra.totalItems).term).to.deep.eq(toRdf(14))
})
})

context('when collection is sourced from another endpoint', () => {
it('should return a stream of members', async function () {
// given
const kopflos = await startKopflos()

// when
const collection = ex['countries/from-lindas']
const res = await kopflos.handleRequest({
method: 'GET',
iri: collection,
headers: {},
query: {},
body: {} as Body,
})

// then
const dataset = await $rdf.dataset().import(res.body as Stream)
const pointer = $rdf.clownface({ dataset }).node(collection)
expect(pointer.out(ns.hydra.member).terms).to.have.length.above(200)
})
})
})

context('post', () => {
Expand Down
17 changes: 17 additions & 0 deletions packages/hydra/test/collection.test.ts.trig
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,20 @@ GRAPH <municipalities/from-static-district> {
] ;
.
}

GRAPH <countries/from-lindas> {
<countries/from-lindas>
a hydra:Collection ;
hydra:memberAssertion
[
hydra:property rdf:type ;
hydra:object schema:Country ;
] ;
kl:endpoint "lindas" ;
kl-hydra:memberShape
[
sh:property [ sh:path schema:name ] ;
sh:property [ sh:path schema:identifier ] ;
] ;
.
}

0 comments on commit a819ad4

Please sign in to comment.