Background

Dydra is a cloud-based RDF database service that provides a SPARQL endpoint and REST API. This article explains how to programmatically register RDF data using the Dydra API.

Prerequisites

  • A Dydra account
  • An API key
  • A Node.js environment (v16 or later recommended, when using Node.js)

Note: The code examples in this article use the following sample values:

  • Account name: your-account
  • Repository name: your-repository
  • API key: your_api_key_here

When using them in practice, replace these with your own Dydra account information.

API Basics

Endpoint Structure

Base URL: https://dydra.com/{account}/{repository}

Example: https://dydra.com/your-account/your-repository

SPARQL Query: /sparql (GET)
SPARQL Update: /sparql (POST)
Statements: /statements (POST/GET/DELETE)

Authentication

Dydra uses Bearer token authentication:

Authorization: Bearer YOUR_API_KEY

Implementation Methods

Access to the Dydra API can be implemented using various methods such as curl, Python, and Node.js. We introduce each method below.

Method 1: curl Implementation (Simplest)

With curl, you can register data immediately without any programming language.

Basic Authentication

# Set API key as environment variable
export DYDRA_API_KEY="your_api_key_here"
export DYDRA_BASE_URL="https://dydra.com/your-account/your-repository"

Registering Data in Turtle Format

# Register from a data.ttl file
curl -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: text/turtle" \
  --data-binary @data.ttl \
  "${DYDRA_BASE_URL}/statements"

data.ttl example:

@prefix ex:  .
@prefix dcterms:  .

ex:document001 a ex:Document ;
    dcterms:title "Research Report" ;
    ex:storageLocation "osf://project/file.pdf" ;
    ex:fileSize 2048576 .

Registering Inline Data

curl -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: text/turtle" \
  --data '@prefix ex:  .
ex:test001 a ex:Person ;
    ex:name "John Doe" ;
    ex:age 30 .' \
  "${DYDRA_BASE_URL}/statements"

Registering via SPARQL UPDATE

curl -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: application/sparql-update" \
  --data "PREFIX ex:
PREFIX dcterms:

INSERT DATA {
  GRAPH  {
    ex:document002 a ex:Document ;
      dcterms:title \"Technical Document\" ;
      ex:storageLocation \"s3://bucket/doc.pdf\" .
  }
}" \
  "${DYDRA_BASE_URL}/sparql"

Executing SPARQL Queries

# Query with GET request
curl -G \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Accept: application/sparql-results+json" \
  --data-urlencode "query=SELECT * WHERE { ?s ?p ?o } LIMIT 10" \
  "${DYDRA_BASE_URL}/sparql"

Deleting Data

curl -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: application/sparql-update" \
  --data "PREFIX ex:

DELETE WHERE {
  ex:document001 ?p ?o .
}" \
  "${DYDRA_BASE_URL}/sparql"

Registering in JSON-LD Format

curl -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: application/ld+json" \
  --data '{
  "@context": {
    "ex": "http://example.org/",
    "dcterms": "http://purl.org/dc/terms/"
  },
  "@id": "ex:document003",
  "@type": "ex:Document",
  "dcterms:title": "JSON-LD Document",
  "ex:fileSize": 1024000
}' \
  "${DYDRA_BASE_URL}/statements"

curl Script Example

A shell script for registering multiple files in sequence:

#!/bin/bash

DYDRA_API_KEY="your_api_key_here"
DYDRA_BASE_URL="https://dydra.com/your-account/your-repository"

# Register all .ttl files in the data directory
for file in data/*.ttl; do
  echo "Uploading $file..."

  curl -X POST \
    -H "Authorization: Bearer ${DYDRA_API_KEY}" \
    -H "Content-Type: text/turtle" \
    --data-binary @"$file" \
    "${DYDRA_BASE_URL}/statements"

  if [ $? -eq 0 ]; then
    echo "Successfully uploaded $file"
  else
    echo "Failed to upload $file"
  fi

  # Rate limiting
  sleep 1
done

Checking Responses

# Display detailed response
curl -v -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: text/turtle" \
  --data-binary @data.ttl \
  "${DYDRA_BASE_URL}/statements"

# Get only the HTTP status code
curl -o /dev/null -s -w "%{http_code}\n" \
  -X POST \
  -H "Authorization: Bearer ${DYDRA_API_KEY}" \
  -H "Content-Type: text/turtle" \
  --data-binary @data.ttl \
  "${DYDRA_BASE_URL}/statements"

Method 2: Python Implementation

import requests
import os

class DydraClient:
    def __init__(self, api_key, account, repository):
        self.api_key = api_key
        self.base_url = f"https://dydra.com/{account}/{repository}"
        self.headers = {
            "Authorization": f"Bearer {api_key}"
        }

    def insert_turtle(self, turtle_data):
        """Register data in Turtle format"""
        response = requests.post(
            f"{self.base_url}/statements",
            data=turtle_data,
            headers={
                **self.headers,
                "Content-Type": "text/turtle"
            }
        )
        response.raise_for_status()
        return response

    def query(self, sparql):
        """Execute a SPARQL query"""
        response = requests.get(
            f"{self.base_url}/sparql",
            params={"query": sparql},
            headers={
                **self.headers,
                "Accept": "application/sparql-results+json"
            }
        )
        response.raise_for_status()
        return response.json()

    def update(self, sparql):
        """Execute a SPARQL UPDATE"""
        response = requests.post(
            f"{self.base_url}/sparql",
            data=sparql,
            headers={
                **self.headers,
                "Content-Type": "application/sparql-update"
            }
        )
        response.raise_for_status()
        return response

# Usage example
client = DydraClient(
    api_key=os.getenv("DYDRA_API_KEY"),
    account="your-account",
    repository="your-repository"
)

# Register data
turtle = """
@prefix ex:  .
ex:test a ex:Document ;
    ex:title "Test Document" .
"""
client.insert_turtle(turtle)

# Execute query
results = client.query("SELECT * WHERE { ?s ?p ?o } LIMIT 10")
print(results)

Method 3: Node.js/TypeScript Implementation

Basic Setup

First, install the required packages:

npm install axios dotenv

Save the API key in an environment variable file (.env):

DYDRA_API_KEY=your_api_key_here
DYDRA_ACCOUNT=your-account
DYDRA_REPOSITORY=your-repository

Dydra Client Class Implementation

import axios, { AxiosInstance } from 'axios';

interface DydraConfig {
  apiKey: string;
  account: string;
  repository: string;
}

class DydraClient {
  private client: AxiosInstance;
  private baseUrl: string;

  constructor(config: DydraConfig) {
    this.baseUrl = `https://dydra.com/${config.account}/${config.repository}`;

    this.client = axios.create({
      baseURL: this.baseUrl,
      headers: {
        'Authorization': `Bearer ${config.apiKey}`,
      },
    });
  }

  /**
   * Register data in Turtle format
   */
  async insertTurtle(turtle: string): Promisevoid> {
    try {
      await this.client.post('/statements', turtle, {
        headers: { 'Content-Type': 'text/turtle' }
      });
      console.log('Data inserted successfully');
    } catch (error) {
      this.handleError(error, 'insertTurtle');
    }
  }

  /**
   * Execute a SPARQL UPDATE query
   */
  async update(sparql: string): Promisevoid> {
    try {
      await this.client.post('/sparql', sparql, {
        headers: { 'Content-Type': 'application/sparql-update' }
      });
      console.log('Update executed successfully');
    } catch (error) {
      this.handleError(error, 'update');
    }
  }

  /**
   * Execute a SPARQL query
   */
  async query(sparql: string): Promiseany> {
    try {
      const response = await this.client.get('/sparql', {
        params: { query: sparql },
        headers: { 'Accept': 'application/sparql-results+json' }
      });
      return response.data;
    } catch (error) {
      this.handleError(error, 'query');
    }
  }

  /**
   * Register data in JSON-LD format
   */
  async insertJSONLD(jsonld: object): Promisevoid> {
    try {
      await this.client.post('/statements', jsonld, {
        headers: { 'Content-Type': 'application/ld+json' }
      });
      console.log('JSON-LD inserted successfully');
    } catch (error) {
      this.handleError(error, 'insertJSONLD');
    }
  }

  /**
   * Delete data
   */
  async delete(sparql: string): Promisevoid> {
    try {
      await this.client.post('/sparql', sparql, {
        headers: { 'Content-Type': 'application/sparql-update' }
      });
      console.log('Data deleted successfully');
    } catch (error) {
      this.handleError(error, 'delete');
    }
  }

  private handleError(error: any, operation: string): never {
    if (axios.isAxiosError(error)) {
      const status = error.response?.status;
      const data = error.response?.data;

      console.error(`Error in ${operation}:`);
      console.error(`   Status: ${status}`);
      console.error(`   Message: ${data}`);

      if (status === 401) {
        throw new Error('Authentication failed. Check your API key.');
      } else if (status === 400) {
        throw new Error(`Bad request: ${data}`);
      }
    }
    throw error;
  }
}

export default DydraClient;

Node.js Usage Example

Basic Data Registration

import DydraClient from './DydraClient';
import dotenv from 'dotenv';

dotenv.config();

const client = new DydraClient({
  apiKey: process.env.DYDRA_API_KEY!,
  account: process.env.DYDRA_ACCOUNT!,
  repository: process.env.DYDRA_REPOSITORY!,
});

// Register in Turtle format
const turtle = `
@prefix ex:  .
@prefix dcterms:  .
@prefix xsd:  .

ex:document001 a ex:Document ;
    dcterms:title "Research Report 2025" ;
    ex:storageLocation "osf://project123/report.pdf" ;
    ex:fileSize 2048576 ;
    ex:checksum "sha256:abc123..." ;
    dcterms:created "2025-10-10T10:00:00Z"^^xsd:dateTime .
`;

await client.insertTurtle(turtle);

Registering via SPARQL UPDATE

const sparqlInsert = `
PREFIX ex:
PREFIX dcterms:

INSERT DATA {
  GRAPH  {
    ex:document002 a ex:Document ;
      dcterms:title "Technical Document" ;
      ex:storageLocation "s3://bucket/tech-doc.pdf" ;
      ex:fileSize 1024000 .
  }
}
`;

await client.update(sparqlInsert);

Searching Data

const results = await client.query(`
  PREFIX ex:
  PREFIX dcterms:

  SELECT ?doc ?title ?location WHERE {
    ?doc a ex:Document ;
         dcterms:title ?title ;
         ex:storageLocation ?location .
  }
  LIMIT 10
`);

console.log(results);

Comparison of Implementation Methods

MethodAdvantagesDisadvantagesRecommended Use Cases
curlNo environment setup needed, immediate execution, shell script automationComplex logic is difficult, weak error handlingQuick tests, simple batch processing, CI/CD pipelines
PythonReadable, rich libraries, integration with data analysisLower type safetyData analysis, scripting, ML integration
Node.js/TSType safety, good async processing, Web API integrationInitial setup requiredWeb applications, large-scale systems, production environments

Summary

By using the Dydra API, you can flexibly and programmatically manage RDF data.

Guidelines for Choosing an Implementation Method

When to use curl (shell scripts):

  • Quick testing and verification
  • Automation in CI/CD pipelines
  • Minimal environment setup needed
  • Simple batch processing

When to use Python:

  • Integration with data analysis
  • Integration with machine learning pipelines
  • Complex data transformation processing
  • Prototyping in Jupyter Notebooks

When to use Node.js/TypeScript:

  • Web application development
  • When type safety is important
  • Large-scale systems
  • Long-term production operations

Important Points

  1. API key management: Use environment variables; never hardcode in source code
  2. Error handling: Implement retry logic and appropriate log output
  3. Rate limiting: Set appropriate delays between requests
  4. Validation: Check RDF syntax before registering data
  5. Batch processing: Process large volumes of data in chunks

Next Steps

Use the patterns introduced in this article to build a robust RDF data management system.

References