S3
SPARQL Anything can read a resource stored in an Amazon S3 bucket, or in any S3-compatible object storage service (e.g. MinIO), as the input of a query.
Unlike the built-in location-based sources (local files, HTTP(S) URLs), S3 support is not bundled with the core engine. It is provided by a separate module, sparql-anything-s3-support, which plugs into the engine through the same service-provider mechanism used for every other input source.
Adding the dependency
To enable S3 support, add the module to your project's dependencies:
<dependency>
<groupId>io.github.sparql-anything</groupId>
<artifactId>sparql-anything-s3-support</artifactId>
<version>version</version>
</dependency>
No further configuration is needed: once the module is on the classpath, its S3InputService is discovered automatically via ServiceLoader and made available to any query that sets the s3.endpoint property.
Options
| Option name | Description | Required |
|---|---|---|
s3.endpoint |
The URL of the S3-compatible endpoint (e.g. https://s3.amazonaws.com, or the URL of a MinIO instance). Setting this property is what tells SPARQL Anything to route the request through the S3 service instead of a plain HTTP(S) request. |
Yes |
s3.bucket-name |
The name of the bucket containing the object to read. | Yes |
s3.key |
The key (path) of the object within the bucket. | Yes |
s3.access-key |
The access key used to authenticate against the S3-compatible service. | Yes |
s3.secret-key |
The secret key used to authenticate against the S3-compatible service. | Yes |
s3.region |
The AWS region to use (e.g. us-east-1). Required by the AWS SDK even against non-AWS, S3-compatible services such as MinIO. |
Yes |
Example
The following query reads a JSON object stored at key people.json in bucket my-bucket, on a MinIO instance running at http://localhost:9000:
PREFIX fx: <http://sparql.xyz/facade-x/ns/>
PREFIX xyz: <http://sparql.xyz/facade-x/data/>
SELECT ?name WHERE {
SERVICE <x-sparql-anything:> {
fx:properties
fx:media-type "application/json" ;
fx:s3.endpoint "http://localhost:9000" ;
fx:s3.bucket-name "my-bucket" ;
fx:s3.key "people.json" ;
fx:s3.access-key "minioadmin" ;
fx:s3.secret-key "minioadmin" ;
fx:s3.region "us-east-1" .
?root xyz:people/fx:anySlot/xyz:name ?name
}
}
⚠️ media-type must be set explicitly
Unlike location-based resources, where SPARQL Anything can usually guess the right triplifier from the file extension in the URL or from a Content-Type response header, an S3 object carries neither of those signals to the triplifier selection logic. The s3.key is only used to address the object inside the bucket — it is not inspected to infer a media type, and there is no HTTP response to read a Content-Type header from.
As a consequence, you must always set the media-type option explicitly when querying a resource in S3 (e.g. fx:media-type "application/json", fx:media-type "text/csv", etc.), or SPARQL Anything will not know which triplifier to use to parse the resource.
The root of the generated resource
The root of the Facade-X graph generated from an S3 resource is minted from the concatenation of s3.endpoint, s3.bucket-name, and s3.key:
<s3.endpoint>/<s3.bucket-name>/<s3.key>
For the example above, the root would be http://localhost:9000/my-bucket/people.json.
This means two different objects — different bucket, different key, or both — are always minted with distinct roots, even when served from the same endpoint, so you can safely combine data from multiple S3 objects in the same query or dataset without their generated roots colliding.
Testing
S3 support is tested against a real S3-compatible service rather than a mocked one, using Testcontainers to start a disposable MinIO container for the duration of the test. This exercises the real AWS SDK client, the real HTTP connection, and the real builder configuration (endpoint override, path-style access, credentials) end-to-end, which a mock cannot verify.
These tests require a working Docker (or Docker-compatible) engine to be available on the machine running the build. If Docker isn't installed or running, the tests are skipped automatically rather than failing, so the rest of the build is unaffected on machines without Docker.