The project as RDF
Content may include inaccuracies, outdated information, or technical errors. Users are advised to cross-check critical information before implementation.
The content of a project is available as RDF: an object becomes a resource, an attribute and a reference become triples, a model becomes a named graph. A project has a SPARQL endpoint of its own, and a model can be downloaded as Turtle or TriG.
Download a model
- Right-click a model in the model explorer and open Download.
- Choose RDF Turtle or RDF TriG.
Both files carry the same triples. Turtle writes them flat, declaring a prefix for every metamodel the model uses; TriG wraps them in a named graph whose IRI is the download URL of the model - the same IRI the SPARQL endpoint uses.
Both begin with an ontology header: the model is declared an owl:Ontology, and
every metamodel it depends on is listed with owl:imports.
How objects are represented
Open the file. An object is a resource named after its identifier:
urn:uuid:8b1f0d38-6c40-4a1e-9a20-2f8b7d1c5e44
Its rdf:type names its concrete class, and the IRI of a class is the namespace
of the metamodel, #, and the class name:
http://www.archimatetool.com/archimate#BusinessActor
The IRI of a property has one more part: the class that declares the
feature, a dot, and the feature name. BusinessActor has a name, but Nameable
declares it:
?actor archimate:Nameable.name "Customer" .
The same holds for relationships: source and target are declared by
ArchimateRelationship, whatever the concrete type of the relationship is.
An attribute becomes a triple whose object is a literal, a reference becomes a triple whose object is the IRI of the target - containment included, so the folder tree of a model is a chain of reference triples. Only the features that are set produce triples; derived and transient ones produce none.
Queries
Every project has its own SPARQL 1.1 endpoint, answering over all its models at once:
curl -X POST https://architeezy.com/api/projects/$PROJECT/sparql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/sparql-query" \
--data 'SELECT DISTINCT ?g WHERE { GRAPH ?g { ?s ?p ?o } }'
That first query lists the graphs, one per model; keep the IRIs, because an
update has to name its graph. A query without GRAPH reads every model of the
project.
All four query forms work, and the response type follows the form: SELECT
gives application/sparql-results+json, ASK a JSON boolean, CONSTRUCT and
DESCRIBE Turtle.
Add ?inference=rdfs to the URL, and the query runs over the inferred graph, so
a query by a supertype also finds instances of its subtypes.
An anonymous request is refused with 401. A project you may not see answers
404, exactly as a project that does not exist.
Updates
Updates go to a separate address, POST /api/projects/<projectId>/sparql/update
with the content type application/sparql-update, and a successful one answers
204.
Every INSERT and DELETE has to wrap its triples in GRAPH; an update that
leaves them in the default graph is refused with 400. Take the graph IRI from
the query above:
PREFIX archimate: <http://www.archimatetool.com/archimate#>
DELETE {
GRAPH <https://architeezy.com/api/models/acme/landscape/1.0.0/core/content> {
?actor archimate:Nameable.name ?old .
}
}
INSERT {
GRAPH <https://architeezy.com/api/models/acme/landscape/1.0.0/core/content> {
?actor archimate:Nameable.name "Customer" .
}
}
WHERE {
GRAPH <https://architeezy.com/api/models/acme/landscape/1.0.0/core/content> {
?actor a archimate:BusinessActor ;
archimate:Nameable.name ?old .
FILTER (str(?old) = "Client")
}
}
Each model whose graph changed is written back to the repository, and the change
appears in open editors like any other edit. Models you did not touch are left
alone, and an update into a model you may not write is refused with 403.
Uploading RDF
Upload model in the project menu reads .ttl as Turtle and .trig as TriG.
The same content goes through the API with
PUT /api/models/<id>/content?format=ttl.
An import maps RDF onto a metamodel that is already in the repository: it
resolves every rdf:type IRI to a class and every predicate IRI to a feature of
the declaring class, and creates neither. So the file has to match the metamodel
it was written for, and that metamodel has to be visible to the target project.
A statement whose class or property does not resolve is skipped rather than
fatal, and an object of an abstract class is not created.
Identifiers survive: urn:uuid:<id> comes back as the object with that
identifier, so a download and an upload give you the original objects rather
than copies.
A metamodel as an ontology
A metamodel is exported not as data but as the ontology that describes it. Add
/owl to its address:
GET /api/models/<scope>/<project>/<version>/<model>/owl?format=ttl
GET /api/predefined-metamodels/<id>/owl?format=ttl
Classes become resources with rdfs:label and rdfs:subClassOf; attributes and
references become properties with rdfs:domain and rdfs:range, and a
single-valued one is also an owl:FunctionalProperty; opposite references are
joined by owl:inverseOf; an identifying attribute becomes owl:hasKey;
enumerations keep their literals; and a data type implemented by a standard XML
Schema type is declared owl:equivalentClass of it, so String matches
xsd:string.