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();
}
}
- In your project, Add a new operation in your mvc controller
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
example n°1 : find all items with : debit great than or equals to 0 AND i want the 2nd page with 50 items by page
RSQL : debit=ge=0&pageNumber=1&pageSize=50
Request URL : https://localhost:5003/customers?query=debit%3Dge%3D0&page_number=1&page_size=50
example n°2 : find all items with : debit great than or equals to 0 AND i want the first page with 50 items by page AND i sort ascending by name AND i sort descending by credit
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
- See RSql4Net.Samples project for samples
- See https://github.com/jirutka/rsql-parser
- See http://tools.ietf.org/html/draft-nottingham-atompub-fiql-00