Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sparql Client Laravel Package

effectiveactivism/sparql-client

OOP SPARQL 1.1 client (Symfony-focused) supporting SELECT/ASK/CONSTRUCT/DESCRIBE plus full update ops (INSERT/DELETE/REPLACE, graph management). Includes patterns, aggregates, functions, dataset clauses, validation, SHACL support.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:
    composer require effectiveactivism/sparql-client
    
  2. Configure endpoints in config/packages/sparql_client.yaml:
    sparql_client:
      query_endpoint: "http://your-sparql-endpoint/sparql"
      update_endpoint: "http://your-sparql-endpoint/sparql"
    
  3. First Query:
    use EffectiveActivism\SparQlClient\Client\SparQlClientInterface;
    
    public function index(SparQlClientInterface $client) {
        $result = $client->select(['?subject'])
            ->where([new Triple(new Variable('subject'), new PrefixedIri('schema', 'headline'), new PlainLiteral('Test'))])
            ->execute();
        return $result->getRows();
    }
    

First Use Case: Fetching Schema.org Data

$sparql = $client->select(['?article'])
    ->where([new Triple(new Variable('article'), new PrefixedIri('schema', 'type'), new PrefixedIri('schema', 'Article'))])
    ->limit(10);

$articles = $sparql->execute()->getRows();

Implementation Patterns

1. Query Builder Pattern

  • Chaining Methods: Build queries fluently:
    $client->select(['?subject', '?predicate'])
        ->where([$triplePattern])
        ->orderBy([new Asc(new Variable('subject'))])
        ->limit(50);
    
  • Reusable Components: Create helper methods for common queries:
    private function getArticlesWithHeadline(SparQlClientInterface $client, string $headline) {
        return $client->select(['?article'])
            ->where([
                new Triple(new Variable('article'), new PrefixedIri('schema', 'headline'), new PlainLiteral($headline)),
                new Triple(new Variable('article'), new PrefixedIri('rdf', 'type'), new PrefixedIri('schema', 'Article'))
            ]);
    }
    

2. Update Workflows

  • Atomic Operations: Use replace() for DELETE+INSERT:
    $client->replace()
        ->delete([$oldTriplePattern])
        ->insert([$newTriplePattern])
        ->where([$filterTriple])
        ->execute();
    
  • Bulk Updates: Batch operations for performance:
    $triples = [...]; // Array of Triple objects
    $client->insert($triples)->execute();
    

3. Namespace Management

  • Dynamic Namespaces: Set per-query or globally:
    $client->setExtraNamespaces(['foaf' => 'http://xmlns.com/foaf/0.1/']);
    // Or per-statement:
    $statement->setExtraNamespaces(['...']);
    

4. Result Processing

  • Iterative Processing: Stream large results:
    foreach ($result->getRows() as $row) {
        $this->processRow($row);
    }
    
  • Aggregation: Use SelectExpression for computed columns:
    $countExpr = new SelectExpression(new Count(new Variable('subject')), new Variable('count'));
    $client->select(['?subject', $countExpr])->where([...]);
    

5. Error Handling

  • Transaction Rollback: Wrap updates in try-catch:
    try {
        $client->beginTransaction();
        $client->insert([...])->execute();
        $client->commit();
    } catch (\Exception $e) {
        $client->rollback();
        throw $e;
    }
    

Gotchas and Tips

1. Performance Pitfalls

  • Avoid SELECT *: Explicitly list variables to reduce payload:
    // Bad
    $client->select(['*']);
    // Good
    $client->select(['?subject', '?predicate']);
    
  • Use LIMIT Early: Prevent memory issues with large datasets:
    $client->select(['?subject'])->limit(1000)->where([...]);
    
  • Index Awareness: Ensure your SPARQL endpoint has proper indexes for WHERE clauses.

2. Debugging Tips

  • Raw Query Inspection: Log the generated SPARQL:
    $statement = $client->select([...])->where([...]);
    $rawQuery = $statement->getQueryString();
    $this->logger->debug('SPARQL Query:', ['query' => $rawQuery]);
    
  • Endpoint Validation: Verify endpoints return 200 for SELECT/ASK and 204 for updates.

3. Configuration Quirks

  • Endpoint Separation: Some stores (e.g., Oxigraph) require separate query/update endpoints.
  • Authentication: Configure HTTP clients for protected endpoints:
    sparql_client:
      query_endpoint: "https://secure-endpoint/sparql"
      http_client:
        base_uri: "%env(SPARQL_ENDPOINT)%"
        auth_basic: ["%env(SPARQL_USER)%", "%env(SPARQL_PASS)%"]
    

4. Extension Points

  • Custom Terms: Extend TermInterface for domain-specific types:
    class CustomIri implements TermInterface {
        public function __toString() {
            return '<' . $this->iri . '>';
        }
        // Implement other TermInterface methods
    }
    
  • Query Modifiers: Create decorators for cross-cutting concerns (e.g., logging, caching):
    class LoggingSparqlClient implements SparQlClientInterface {
        public function execute(StatementInterface $statement) {
            $this->logger->info('Executing SPARQL:', ['query' => $statement->getQueryString()]);
            return $this->delegate->execute($statement);
        }
    }
    

5. Common Errors

  • Malformed URIs: Validate IRIs before use:
    if (!filter_var($iri, FILTER_VALIDATE_URL)) {
        throw new \InvalidArgumentException("Invalid IRI: $iri");
    }
    
  • Namespace Collisions: Prefix namespaces explicitly:
    // Bad (ambiguous)
    new PrefixedIri('schema', 'headline') // Assumes 'schema' is registered
    // Good (explicit)
    new PrefixedIri('http://schema.org/', 'headline');
    
  • Update Conflicts: Handle 409 Conflict responses gracefully:
    try {
        $client->execute($updateStatement);
    } catch (HttpException $e) {
        if ($e->getStatusCode() === 409) {
            $this->handleConflict();
        }
    }
    

6. SHACL Validation

  • Pre-Update Validation: Validate data before inserting:
    $validator = $client->getShaclValidator();
    $validationReport = $validator->validate($triple, 'http://shacl/shapes/ArticleShape');
    if (!$validationReport->isValid()) {
        throw new \RuntimeException("SHACL validation failed: " . $validationReport->getMessage());
    }
    

7. Docker Integration

  • Local Testing: Use the provided docker-compose for Blazegraph/Oxigraph:
    services:
      blazegraph:
        image: effectiveactivism/sparql-blazegraph:latest
        ports:
          - "9999:9999"
    
  • Persistent Data: Mount volumes for development:
    volumes:
      - ./data:/data
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky