Why RDF Mapper Annotations?
Simplify your RDF data handling with a clean, type-safe approach to mapping between Dart objects and RDF graphs.
Declarative Syntax
Define your data model with simple annotations and let the code generator handle the mapping logic.
Type-Safe
Compile-time checked mappings ensure type safety and catch errors early in the development process.
Flexible IRI Strategies
Customizable IRI generation strategies to fit your application's needs, from simple templates to complex logic.
Lossless RDF Mapping
Perfect round-trip preservation possible with @RdfUnmappedTriples annotation and RdfGraph properties for complete data integrity.
Comprehensive Collection Support
Native support for Lists, Sets, and Maps with customizable serialization strategies.
Native Enum Support
Type-safe enum mapping to RDF literals and IRIs with custom values and template patterns.
Extensible Architecture
Easily extend with custom mappers for specialized data types and complex mapping scenarios.
Part of an Ecosystem
Works seamlessly with other RDF Dart packages for a complete RDF solution.
Quick Start
Get started with just a few annotations and let the code generator do the rest.
import 'package:rdf_core/rdf_core.dart';
import 'package:rdf_mapper_annotations/rdf_mapper_annotations.dart';
import 'package:rdf_vocabularies/schema.dart';
@RdfGlobalResource(
SchemaBook.classIri,
IriStrategy('http://example.org/book/{id}')
)
class Book {
@RdfIriPart()
final String id;
@RdfProperty(SchemaBook.name)
final String title;
@RdfProperty(SchemaBook.author,
iri: IriMapping('http://example.org/author/{authorId}'))
final String authorId;
// Collections are supported out of the box
@RdfProperty(SchemaBook.hasPart)
final List<Chapter> chapters;
Book({
required this.id,
required this.title,
required this.authorId,
required this.chapters,
});
}
@RdfLocalResource(SchemaChapter.classIri)
class Chapter {
@RdfProperty(SchemaChapter.name)
final String title;
@RdfProperty(SchemaChapter.position)
final int number;
Chapter(this.title, this.number);
}
// Enum support with custom values and IRI templates
import 'package:rdf_mapper_annotations/rdf_mapper_annotations.dart';
// Literal enum mapping
@RdfLiteral()
enum BookFormat {
@RdfEnumValue('H')
hardcover, // → "H"
@RdfEnumValue('P')
paperback, // → "P"
ebook, // → "ebook" (default: enum name)
}
// IRI enum mapping with templates
@RdfIri('http://schema.org/{value}')
enum ItemCondition {
@RdfEnumValue('NewCondition')
brandNew, // → <http://schema.org/NewCondition>
@RdfEnumValue('UsedCondition')
used, // → <http://schema.org/UsedCondition>
refurbished, // → <http://schema.org/refurbished>
}
// Using enums in resource classes
@RdfGlobalResource(
SchemaBook.classIri,
IriStrategy('http://example.org/book/{id}')
)
class Book {
@RdfIriPart()
final String id;
@RdfProperty(SchemaBook.bookFormat)
final BookFormat format; // Uses enum's @RdfLiteral mapping
@RdfProperty(SchemaBook.itemCondition)
final ItemCondition condition; // Uses enum's @RdfIri mapping
Book({required this.id, required this.format, required this.condition});
}
# Add dependencies to your pubspec.yaml
dart pub add rdf_core rdf_mapper rdf_mapper_annotations rdf_vocabularies
dart pub add --dev build_runner rdf_mapper_generator
# Generate the mappers
dart run build_runner build --delete-conflicting-outputs
// main.dart
import 'package:rdf_core/rdf_core.dart';
import 'package:rdf_mapper/rdf_mapper.dart';
import 'package:rdf_mapper_annotations/rdf_mapper_annotations.dart';
// Import the generated mapper initialization file
import 'rdf_mapper.g.dart';
void main() {
// Initialize the generated mapper
final mapper = initRdfMapper();
// Create a book with chapters
final book = Book(
id: '123',
title: 'RDF Mapping with Dart',
authorId: 'dart-dev', // Will be mapped to http://example.org/author/dart-dev
chapters: [
Chapter('Introduction', 1),
Chapter('Advanced Mapping', 2),
],
);
// Convert to serialized format (Turtle, JSON-LD, etc.)
final turtle = mapper.encodeObject(book);
print('=== Serialized RDF (Turtle) ===');
print(turtle);
// Parse back to Dart object
final parsedBook = mapper.decodeObject<Book>(turtle);
print('\n=== Deserialized Book ===');
print('Title: ${parsedBook.title}');
print('Author ID: ${parsedBook.authorId}');
print('Chapters:');
for (final chapter in parsedBook.chapters) {
print('- ${chapter.title} (#${chapter.number})');
}
}