The official SurrealDB library for .NET.
dotnet add package SurrealDb.Net
Supported protocols:
- ✅ HTTP(S)
- ✅ WS(S)
- 🚧 and more to come...
You can easily create a new SurrealDB client easily. All you have to do is define the endpoint
to the SurrealDB instance.
var clientHttp = new SurrealDbClient("http://127.0.0.1:8000");
var clientHttps = new SurrealDbClient("https://cloud.surrealdb.com");
var clientWs = new SurrealDbClient("ws://127.0.0.1:8000/rpc");
var clientWss = new SurrealDbClient("wss://cloud.surrealdb.com/rpc");
// Signin & Use ns/db
There are some static constructors that you can use for specific contexts. The advantage of this syntax is that all you only need to do is define the host
and not the endpoint
.
var clientHttp = SurrealDbHttpClient.New("127.0.0.1:8000");
var clientHttps = SurrealDbHttpsClient.New("cloud.surrealdb.com");
var clientWs = SurrealDbWsClient.New("127.0.0.1:8000");
var clientWss = SurrealDbWssClient.New("cloud.surrealdb.com");
// Signin & Use ns/db
Last but not least, you can use Dependency Injection with the services.AddSurreal()
function.
var options = SurrealDbOptions
.Create()
.WithEndpoint("http://127.0.0.1:8000")
.WithNamespace("test")
.WithDatabase("test")
.WithUsername("root")
.WithPassword("root")
.Build();
services.AddSurreal(options);
Then you will be able to use the ISurrealDbClient
interface or SurrealDbClient
class anywhere.
public class MyClass
{
private readonly ISurrealDbClient _client;
public MyClass(ISurrealDbClient client)
{
_client = client;
}
// ...
}
Note that the default lifetime of this service is Singleton
. You can override this as follows:
services.AddSurreal(options, ServiceLifetime.Scoped);
Consider the following appsettings.json
file:
{
"AllowedHosts": "*",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"SurrealDB": "Server=http://127.0.0.1:8000;Namespace=test;Database=test;Username=root;Password=root"
}
}
You can use the Connection String instead of having to deal with a SurrealDbOptions
.
services.AddSurreal(configuration.GetConnectionString("SurrealDB"));
It will automatically create a new SurrealDB using the Server endpoint
and configure the client using the different values for namespace
, database
, username
and password
. Note that these values are optional but the endpoint
is still required.
Having a default instance for a project is enough most of the time, but there may be times when you'd like to target multiple SurrealDB instances, either at different addresses or at the same address but inside different NS/DBs. You can use multiple instances as long as you provide 1 interface per client, as in the following example.
interface IBackupSurrealDbClient : ISurrealDbClient { }
interface IMonitoringSurrealDbClient : ISurrealDbClient { }
services.AddSurreal(configuration.GetConnectionString("SurrealDB.Main"));
services.AddSurreal<IBackupSurrealDbClient>(configuration.GetConnectionString("SurrealDB.Backup"));
services.AddSurreal<IMonitoringSurrealDbClient>(configuration.GetConnectionString("SurrealDB.Monitoring"));
Here you will have 3 instances:
- the default one, you can keep using
ISurrealDbClient
interface orSurrealDbClient
class anywhere - a client for backup purpose, using the
IBackupSurrealDbClient
interface - a client for monitoring purpose, using the
IMonitoringSurrealDbClient
interface
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private const string Table = "weatherForecast";
private readonly ISurrealDbClient _surrealDbClient;
public WeatherForecastController(ISurrealDbClient surrealDbClient)
{
_surrealDbClient = surrealDbClient;
}
[HttpGet]
[Route("/")]
public Task<List<WeatherForecast>> GetAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Select<WeatherForecast>(Table, cancellationToken);
}
[HttpGet]
[Route("/{id}")]
public async Task<IActionResult> Get(string id, CancellationToken cancellationToken)
{
var weatherForecast = await _surrealDbClient.Select<WeatherForecast>(Table, id, cancellationToken);
if (weatherForecast is null)
return NotFound();
return Ok(weatherForecast);
}
[HttpPost]
[Route("/")]
public Task<WeatherForecast> Create(CreateWeatherForecast data, CancellationToken cancellationToken)
{
var weatherForecast = new WeatherForecast
{
Date = data.Date,
Country = data.Country,
TemperatureC = data.TemperatureC,
Summary = data.Summary
};
return _surrealDbClient.Create(Table, weatherForecast, cancellationToken);
}
[HttpPut]
[Route("/")]
public Task<WeatherForecast> Update(WeatherForecast data, CancellationToken cancellationToken)
{
return _surrealDbClient.Upsert(data, cancellationToken);
}
[HttpPatch]
[Route("/{id}")]
public Task<WeatherForecast> Patch(string id, Dictionary<string, object> data, CancellationToken cancellationToken)
{
var thing = new Thing(Table, id);
return _surrealDbClient.Patch<WeatherForecast>(thing, data, cancellationToken);
}
[HttpDelete]
[Route("/")]
public Task DeleteAll(CancellationToken cancellationToken)
{
return _surrealDbClient.Delete(Table, cancellationToken);
}
[HttpDelete]
[Route("/{id}")]
public async Task<IActionResult> Delete(string id, CancellationToken cancellationToken)
{
bool success = await _surrealDbClient.Delete(Table, id, cancellationToken);
if (!success)
return NotFound();
return Ok();
}
}
This project was written following testing best practices:
- TDD, leveraging:
- clean code/architecture
- regression testing
- adding new features and tests easily
- xUnit and FluentAssertions libraries
- a vast majority of tests are integration tests, ensuring compatibility with a concrete SurrealDB version
- each integration test is using a separate SurrealDB instance
The .NET release versions must follow these rules:
- Should target at least the latest LTS (Long-Term Support) version
- Should target at least the latest STS (Standard-Term Support) version
SurrealDb.Net targets .NET versions following the .NET Support Policy by Microsoft. Additionally, SurrealDb.Net targets .NET Standard 2.1 explicitly to continue support of the Mono runtime (Unity, Xamarin, etc...).
Note that the support for .NET standard 2.1 will be maintained until further notice.
Version | Description | Release Date | End of Support |
---|---|---|---|
.NET Standard 2.1 | June 27, 2016 | N/A | |
.NET 6 | LTS | November 8, 2021 | November 12, 2024 |
.NET 7 | STS | November 8, 2022 | May 14, 2024 |
.NET 8 | Current LTS | November 14, 2023 | November 10, 2026 |
Unit/Integration tests are written using xUnit and FluentAssertions.
You will need a local SurrealDB instance alongside the tests. Start one using the following command:
surreal start --log debug --user root --pass root memory --auth --allow-guests
Once ready, go to the root directory of the project and run the following command:
dotnet watch test --project SurrealDb.Net.Tests
Due to the asynchronous nature of Live Queries, they are tested against a separate project named SurrealDb.Net.LiveQuery.Tests
. Where the default test project allow full parallelization, this project completely disable test parallelization. To execute tests on Live Queries, run the following command:
dotnet watch test --project SurrealDb.Net.LiveQuery.Tests
Note 1: Because Live Query tests are not run in parallel, it can take quite some time to run all tests.
Note 2: You can run the two test projects in parallel.
This project also contains benchmarks in order to detect possible performance regressions.
You will need a local SurrealDB instance alongside the tests. Start one using the following command:
surreal start --user root --pass root memory --auth --allow-guests
Once ready, go to the root directory of the project and run the following command:
dotnet run -c Release --project SurrealDb.Net.Benchmarks --filter '*'