View on GitHub
BitBadger.Documents provides a lightweight document-style interface over PostgreSQL and SQLite's JSON storage capabilities, with first-class support for both C# and F# programs. (It is developed by the community; it is not officially affiliated with either project.)
dotnet add package BitBadger.Documents.Postgres
dotnet add package BitBadger.Documents.Sqlite
- Getting Started provides an overview of the libraries' functions, how to provide connection details, and how to ensure required tables and indexes exist.
- Basic Usage details document-level retrieval, persistence, and deletion.
- Advanced Usage demonstrates how to use the building blocks provided by this library to write slightly-more complex queries.
Document databases usually store JSON objects (as their “documents”) to provide a schemaless persistence of data; they also provide fault-tolerant ways to query that possibly-unstructured data. MongoDB was the pioneer and is the leader in this space, but there are several who provide their own take on it, and their own programming API to come along with it. They also usually have some sort of clustering, replication, and sharding solution that allows them to be scaled out (horizontally) to handle a large amount of traffic.
As a mature relational database, PostgreSQL has a long history of robust data access from the .NET environment; Npgsql is actively developed, and provides both ADO.NET and EF Core APIs. PostgreSQL also has well-established, battle-tested horizontal scaling options. Additionally, the Npgsql.FSharp project provides a functional API over Npgsql's ADO.NET data access. These three factors make PostgreSQL an excellent choice for document storage, and its relational nature can help in areas where traditional document databases become more complex.
SQLite is another mature relational database implemented as a single file, with its access run in-process with the calling application. It works very nicely on its own, with caching and write-ahead logging options; a companion project called Litestream allows these files to be continuously streamed elsewhere, providing point-in-time recovery capabilities one would expect from a relational database. Microsoft provides ADO.NET (and EF Core) drivers for SQLite as part of .NET. These combine to make SQLite a compelling choice, and the hybrid relational/document model allows users to select the model of data that fits their model the best.
In both cases, the document access functions provided by this library are dead-simple. For more complex queries, it also provides the building blocks to construct these with minimal code.
Why Not [something else]?
We are blessed to live in a time where there are a lot of good data storage options that are more than efficient enough for the majority of use cases. Rather than speaking ill of other projects, here is the vision of the benefits these libraries aim to provide:
PostgreSQL is the most popular non-WordPress database for good reason.
- Quality - PostgreSQL's reputation is one of a rock-solid, well-maintained, and continually evolving database.
- Availability - Nearly every cloud database provider offers PostgreSQL, and for custom servers, it is a package install away from being up and running.
- Efficiency - PostgreSQL is very efficient, and its indexing of JSONB allows for quick access via any field in a document.
- Maintainability - The terms “separation of concerns” and “locality of behavior” often compete within a code base, and separation of concerns often wins out; cluttering your logic with SQL can be less than optimal. Using this library, though, it may separate the concerns enough that the calls can be placed directly in the regular logic, providing one fewer place that must be looked up when tracing through the code.
- Simplicity - SQL is a familiar language; even when writing manual queries against the data store created by this library, everything one knows about SQL applies, with a few operators added.
- Reliability - The library has a full suite of tests against both the C# and F# APIs, run against every supported PostgreSQL version to ensure the functionality provided is what is advertised.
The SQLite “About” page has a short description of the project and its strengths. Simplicity, flexibility, and a large install base speak for themselves. A lot of people believe they will need a lot of features offered by server-based relational databases, and live with that complexity even when the project is small. A smarter move may be to build with SQLite; if the need arises for something more, the project is very likely a success!
Many of the benefits listed for PostgreSQL apply here as well, including its test coverage - but SQLite removes the requirement to run it as a server!
Issues can be filed on the project's GitHub repository.