We are so excited to announce the preview release of RESTier – a new middle-ware approach RESTful API development framework for building standardized, OData V4 based REST services.

What is RESTier

RESTier is a RESTful API development framework for building standardized, OData V4 based REST services on .NET. It can be seen as a middle-ware on top of Web API OData. RESTier can provide convenience to bootstrap an OData service and add business logic like what WCF Data Services does as well as flexibily and easy customization like what Web API OData does.

How RESTier Solve Your Problems

In this section, we will show you how RESTier solve the developers' problems. We have a REST developer named Mark and we will use RESTier to meet his needs.

Mark wants to build an OData service against the Northwind database to provide an easy API for users to access and operate on the data. He has used Entity Framework tools to generate the model class from the database and now he wants to bootstrap the OData service in a few minutes.

RESTier can easily satisfy Mark's needs. All he has to do is to add around 20 lines of code as below:

Add an NorthwindDomain.cs to Models. The DbDomain is for handling the domain logic of an OData service. Since Mark just wants an easy bootstrap, he only needs to return the DbContext now.

    public class NorthwindDomain : DbDomain<NorthwindContext>
        public NorthwindContext Context
            get { return DbContext; }

Add an NorthwindController.cs to Controllers which inherits from ODataDomainController instead of ODataController. There are around 10 entity sets in Northwind and Mark only need ONE controller with 3 lines of code instead of ten controllers with tens and hundreds lines of boilerplate code.

    public class NorthwindController : ODataDomainController<NorthwindDomain>
        private NorthwindContext DbContext
            get { return Domain.Context;}

Modify the WebApiConfig.cs file as below. Mark only needs around 5 lines of code instead of specificly include every entity sets in the config file.

    public static class WebApiConfig
        public static void Register(HttpConfiguration config)
            RegisterNorthwind(config, GlobalConfiguration.DefaultServer);
<p>        public static async void RegisterNorthwind(HttpConfiguration config, HttpServer server)
            await config.MapODataDomainRoute<NorthwindController>(
               "NorthwindApi", "api/Northwind",
                new ODataDomainBatchHandler(server));

After these 3 steps above, a RESTful service is bootstraped using RESTier.

With RESTier, Mark has successfully built the RESTful service against his data source. Now he got several asks from customers of adding business logic to this service.

  • Customer A says besides the current Orders, he also wants an entity set CurrentOrders which haven't been shipped yet.

    With RESTier, Imperative Views can make this ask work by adding some code in NorthwindDomain.cs

            protected IQueryable<Order> CurrentOrders
                    return this.Source<Order>("Orders").Where(o => o.ShippedDate == null);
  • Customer B says he only cares Customers from France and he doesn't want to add a $filter query for every request.

    With RESTier, Entity Set Filters can make this work by adding some code in NorthwindDomain.cs

            private IQueryable<Customer> OnFilterCustomers(IQueryable<Customer> customers)
                return customers.Where(c => c.Country == "France");
  • Customer C says he has some additional logic when he deletes an Product

    With RESTier, Submit Logic can make this work by adding some code in NorthwindDomain.cs

            private void OnDeletingProducts(Product product)
                // User logic code when deleting a product.
  • Customer D says he only wants users to have READ permission on Suppliers

    With RESTier, Role-based Security can make this work by adding some code in NorthwindDomain.cs

            // Grant ALL permission on other entity sets. Just put Customers here and omit others.
            [Grant(DomainPermissionType.All, On = "Customers")]
            // Grant only read pemission on Suppliers
            [Grant(DomainPermissionType.Inspect, On = "Suppliers")]
            [Grant(DomainPermissionType.Read, On = "Suppliers")]
            public class NorthwindDomain : DbDomain<NorthwindContext>
               // code

Behind the Scenes

After the previous section of introducting how RESTier help solve your problems, now let's take a deeper look at RESTier itself. And please be noted that RESTier is currently an alpha version, so there are still some limitions.

Structure of RESTier

From the picture below, you can easily find out that client request is handled by Web API OData and RESTier, and RESTier then handle the request and response with the data source. Currently when talking to data source, RETier only supports using EF as data proxy (data provider). RESTier1 RESTier itself has three main modules : Model, Query and Submit (as shown below). Model mainly focus on model producing, Query mainly handles GET request and Submit handles CREATE, UPDATE and DELETE request. These are all based on OData EDM Model. RESTier2

Features supported by RESTier

Basic OData V4 features

  • Basic queries for metadata and top level entities.
  • System query options $select, $expand, $filter, $orderby, $top, $skip, $orderby, $format.
  • Requesting related entities.
  • Create, Update and Delete on top-level entities
  • Batch request

Falling back to Web API OData

As mentioned above, RESTier is based on Web API OData, for some features not directly supported by RESTier, there are easy ways to fall back to Web API OData by using attribute routing. Please refer to RETier wiki for more detailed examples.

Call to Actions

Feedbacks and bug reports. As mentioned previously, currently RESTier is an alpha version, for any feedbacks and bug report, please Open GitHub issues directly or Join OData Mailing List to discusss.

Contribute to RETier. RESTier is fully open sourced, please refer to How to contribute to RESTier to contribute either code or documentation.