Connector Examples
Drop-in starters for the file formats and databases you're most likely to encounter when feeding a Curiosity workspace. Each page covers:
- The NuGet package(s) you need on top of
Curiosity.Library. - A minimal schema (one
[Node]POCO, one[Key]). - A full
Program.csthat streams the source, maps each record, and commits. - Notes on idempotency, large-file handling, and the source-specific gotchas.
These are templates — copy one, point it at your source, and adjust the schema. For the underlying API see Schemas, Ingestion, and Idempotency.
Index
JSON
Stream a JSON array of records with System.Text.Json.JsonSerializer.DeserializeAsyncEnumerable. Constant memory, no third-party dependencies.
Parquet
Stream columnar rows with Parquet.Net. Reads one row-group at a time — works on multi-GB files.
Excel (.xlsx)
Iterate worksheet rows with ClosedXML or ExcelDataReader. Handles formulas and typed cells.
SQL Database
Cursor-paginated SELECT with Dapper over your provider (SQL Server, PostgreSQL, MySQL, SQLite, …).
Common scaffolding
Every example in this folder follows the same shape:
using Curiosity.Library;
[Node]
public class MyRecord
{
[Key] public string Id { get; set; }
[Property] public string Name { get; set; }
[Timestamp] public DateTimeOffset Time { get; set; }
}
using var graph = Graph.Connect(
endpoint: Environment.GetEnvironmentVariable("CURIOSITY_ENDPOINT")!,
token: Environment.GetEnvironmentVariable("CURIOSITY_TOKEN")!,
connectorName: "my-connector");
await graph.CreateNodeSchemaAsync<MyRecord>();
graph.SetAutoCommitCost(everyNodes: 10_000);
// ... read records from source, graph.AddOrUpdate(...) ...
await graph.CommitPendingAsync();
The only thing that changes per format is the reader. The [Node] POCO and the commit loop stay the same. Read Schemas and Ingestion once and the rest is mechanical.
Picking the right reader
| Source | Reader | Why |
|---|---|---|
| Small JSON (< 100 MB), simple shape | JsonSerializer.Deserialize on the whole file |
Simplest, no async-stream complexity. |
| Large or unknown-size JSON | DeserializeAsyncEnumerable or Utf8JsonReader |
Constant memory regardless of file size. |
| CSV with header row | CsvHelper with ClassMap or attribute-based mapping |
Handles quoting, escaping, culture, type conversion. |
| Columnar bulk data | Parquet.Net | Reads compressed columns lazily — orders of magnitude faster on wide rows. |
| Excel as an integration surface | ClosedXML for write-back; ExcelDataReader for read-only ingest | ClosedXML is full-fidelity; ExcelDataReader is faster for huge sheets. |
| Existing relational system | Dapper + the right ADO.NET provider | Cursor-paginated reads keep memory bounded; provider handles drivers. |
| XML feed | XmlReader.Create with a streaming loop |
Built-in to .NET, constant memory. |