RSql4Net is a aspNet .net core extension that will make it easier for you to write your REST APIs. Its purpose is to convert a HTTP request who is in RSQL format to C# lambda expression.
Branch | Build | Quality Gate |
---|---|---|
master | ||
develop |
Installation
Quick start
Documentation
Samples
dotnet add package RSql4Net
Add the RSql4Net nuget package in your project.
In your project, modify the Startup.cs class to add the RSql extension
using RSql4Net;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.AddRSql();
}
}
using RSql4Net.Models;
using RSql4Net.Controllers;
using RSql4Net.Models.Paging;
using RSql4Net.Models.Queries;
namespace MyNamespace
{
public MyController : Controller
{
private IList<MyModel> _myRepository;
public MyController(IList<MyModel> myRepository) {
_myRepository == myRepository ?? throw new ArgumentNullReferenceException(nameof(myRepository));
}
/// <summary>
/// Get resource items by RSql Query and Pageable Query
/// </summary>
/// <param name="query"></param>
/// <param name="pageable"></param>
/// <returns></returns>
[HttpGet]
public IActionResult Get([FromQuery] IRSqlQuery<MyModel> query,[FromQuery] IRSqlPageable<MyModel> pageable)
{
// is not valid request
if (!ModelState.IsValid)
{
return BadRequest(new ErrorModel(ModelState));
}
// use the extension method from RSql4Net.Models.QueryableExtensions.cs
var page = _myRepository
.AsQueryable()
.Page(pageable, query);
// 200 OK : if result page contains all items from in repository
// 206 Partial : if the result page contains a part of items from repository
// use the extension method from RSql4Net.Controllers.ControllerBaseExtensions.cs
return this.Page(page);
}
}
}
This objects define the RSql Query.
Operation | Description |
---|---|
Value | contains the Query string parameters converted to C# Lambda Expression. |
These objects define the paging and sorting criteria to apply.
Operation | Description |
---|---|
PageSize | defined the size of page to return |
PageNumber | defined the page number to return |
Sort | contains the list of sorts to apply (see RSqlSort) |
Operation | Description |
---|---|
Value | value of sort |
IsDescending | defines if sort is descending or ascending |
Operation | Description |
---|---|
TotalElements | total count of element returned by where clause |
Number | current number page |
NumberOfElement | count of elements in the current page |
TotalPages | total count of pages |
HasContent | does the current page contains elements ? |
HasPrevious | does the current page have a previous page ? |
HasNext | does the current page have a next page ? |
To change query string parameter names, you could modify the RSql configuration like the below sample.
using RSql4Net;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddControllers()
.AddRSql(
options =>
options
// change the query string parameter name for RSql query field
.QueryField("q")
// change the query string parameter name for page size field
.PageSizeField("si")
// change the query string parameter name for page number field
.PageNumberField("of")
// change the default page size
.PageSize(50)
);
}
}
To add a cache Memory to RSql queries, you could modify the RSql configuration like below sample.
using RSql4Net;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// we create the RSql cache memory
var memoryCache = new MemoryCache(
new MemoryCacheOptions()
{
SizeLimit = 1024
}
);
services
.AddRSql(
options =>
// we define the memory cache who is used for RSql queries
.QueryCache(memoryCache)
// we define a function who is invoked when register a new Rsql query in memory cache
.OnCreateCacheEntry((o) =>
{
o.Size = 1024;
o.SlidingExpiration = TimeSpan.FromSeconds(25);
o.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5);
})
);
}
}
To add a Swashbuckle OpenAPI support to RSql queries, you could modify the RSql configuration like the below sample.
using RSql4Net.SwaggerGen;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
// add supported to Rsql SwaggerGen Documentation
c.OperationFilter<RSqlOperationFilter>();
}
}
}
Update the appsettings.json file with debug level for RSql4net namespace
{
"Logging": {
"LogLevel": {
"RSql4Net":"Debug"
}
}
}
In the console ...
using RSql4Net.Models.Paging;
namespace RSql4Net.Samples
{
public class Customer {
/// <summary>
/// get of set LastName
/// </summary>
public string LastName {get; set; }
/// <summary>
/// Get or Set FirstName
/// </summary>
public string FirstName {get; set; }
}
public class CustomerDto
{
/// <summary>
/// Get of Set Name
/// </summary>
public string Name { get; set; }
}
/// <summary>
/// sample
/// </summary>
public static class MyConversionHelper
{
public static IRSqlPage<CustomerDto> Convert(IRSqlPage<Customer> src)
{
//use "As" method on IRSqlPage<T>
// and create your selector ...
return src.As(
c => new CustomerDto() {Name = string.Concat(c.LastName, "", c.FirstName)});
}
}
}
To try sample, you can build docker build file. In the project directory ...
docker build -t rsql4net-sample:latest .
docker run -p 5001:5001 rsql4net-sample:latest -d
go to http://localhost:5001/swagger
Binary operator | |
---|---|
and | ; |
or | , |
Comparison operator | |
---|---|
equals | == or =eq= |
not equals | != or =neq= |
lower than | < or =lt= |
lower than or equals | <= or =le= |
greater than | > or =gt= |
greater than or equals | >= or =ge= |
in | =in=(,) |
not in | =out=(,) |
is null | =is-null='true|false' or =nil='true|false' |
Examples of RSql expressions in both FIQL-like:
with customer json model like ,
{
"address": {
"city": "Port Lenorefort",
"street": "18304 Casper Trail",
"country": "Palestinian Territory",
"zipcode": "22270"
},
"birth_date": "2003-08-02T21:25:27.3902975+02:00",
"company": "Hilll LLC",
"email": "Elwin.Jenkins@gmail.com",
"id": 1,
"name": "West",
"phone": "957.379.6587",
"username": "Amalia.Stroman8",
"website": "https://lou.name",
"debit": 0.171063486566331,
"credit": 0.5955531883964097
}
RSQL : name==West;debit=gt=0
Request URL : https://localhost:5003/customers?query=name%3D%3DWest%3Bdebit%3Dgt%3D0
RSQL : address.city==Pales*,name=in=(West,East)
Request URL : https://localhost:5003/customers?query=address.city%3D%3DPales%2A%2Cname%3Din%3D%28West%2CEast%29
RSQL : debit=ge=0&pageNumber=1&pageSize=50
Request URL : https://localhost:5003/customers?query=debit%3Dge%3D0&page_number=1&page_size=50
RSQL : debit=ge=0&pageNumber=1&pageSize=50&sort=name;asc&sort=credit;desc
Request URL : https://localhost:5003/customers?query=debit%3Dge%3D0&page_number=0&page_size=50&sort=name%3Basc&sort=credit%3Bdesc