Put very simply, it is a .NET platform used to create REST services inspired by WCF Web API 0.6.0.0. SimpleRest was designed to be extremely light weight, powerful, extensible, and very easy to use. SimpleRest does not try to get cute or tricky with the code like other platforms tend to do but rather it employs a very simple methodology… The KISS principle. Simple is better.
Creating web API’s are becoming more and more common these days because of the obvious power that they can bring a business. This means that the right technology can become very important and choosing the right one that suites your needs is something that is also very important. Something to look for when choosing these technologies for your organization might be: Ease of use, ability to get something created quickly, maintainability, ability to support independent scaling of services, etc… The good news is that SimpleRest was created with just these types of things in mind. SimpleRest was created to address business needs and cater to developers writing business applications.
As well as being positively inspired by WCF Web API 0.6.0.0 it was also inspired by ASP.NET MVC4 Web API in that ASP.NET MVC4 Web API is a true step backwards from WCF Web API 0.6.0.0 (in my opinion of course).
Some might ask the very obvious question, “why would I not just use ASP.NET MVC4 WebAPI for my web API’s?”. Hell, its Microsoft and comes out of the box with MVC4 now so why wouldn’t you use it right? I will admit that having a native “out of the box” platform that solves the problem that you are trying to solve is quite appealing but as your services start getting more mature and your knowledge of how your services should be created matures you will quickly find out that this platform is very limiting and might not operate as you think it should. Maybe it is the lack of ability to create endpoints for particular sub-resources. Maybe it is the confusing way that HttpRoute’s get registered. Or maybe it is because simply creating a service requires THIRTY FIVE (35) assembly dependencies in your project to drive the platform. Whatever your reason is that upsets you about the way ASP.NET MVC4 Web API does business it is clear that it does not Keep It Stupid Simple as it should.
Additionally, ASP.NET MVC4 Web API suggests that your web application can, and maybe should, live with your web API. This is a very bad idea to suggest things like this as services living within the web application can become problematic for many reasons. Separation of concerns is something that every developer should go out of their way to do so why would you use a platform that suggests that you should marry the concerns of web services and web applications?
There are many more classes within the SimpleRest project. Feel free to browse them for a more in depth understanding of the pipeline.
This is the assembly that drives the SimpleRest platform. With this single assembly you can create rest services using the SimpleRest platform. This assembly was designed to be as light weight as possible only containing dependencies on the following .NET assemblies: Microsoft.CSharp, System, System.Web, System.Web.Routing.
This assembly does not contain any pre-defined media type formatters out of the box so any media type formatters you would like to use would need to be created and wired up to the Configuration object. The SimpleRest.Core.Extensions assembly contains default media type formatters that you can choose to use if you wish.
This assembly wires up a default error handler for the developer which can be overridden within the configuration object. The default behavior returns 501 (Not Implemented) if one of the following exceptions was thrown: NotImplementedException, InvalidOperationException, NotSupportedException. The default behavior returns 400 (Bad Request) in any other circumstances. The default error code is 400 (Bad Request) unless otherwise set in the error handler for any exceptions thrown throughout the SimpleRest pipeline execution.
This assembly was created to address any type of serialization problems or enhancements.
This assembly contains an XSD serializer which will turn a System.Type into its associated XSD in string format. This was created so that XSD’s could be supplied to developers consuming the service to better describe the resource that a particular endpoint is targeting.
This assembly also contains a custom XML serializer which can be used in place of the Microsoft XML serializer. The idea was to create a more verbose xml serializer while making it faster and easier to use. The developer can choose to use this or to simply use another XML serializer.
This assembly is still a light weight assembly but not as light weight as the SimpleRest.Core assembly. This assembly contains dependencies on the following assemblies: Microsoft.CSharp, Newtonsoft.Json (Json.NET), System, System.Web, System.Web.Routing, System.Xml, SimpleRest.Core, SimpleRest.Serialization.
This assembly’s purpose is to extend the functionality of SimpleRest.Core. The reason a new assembly was created to do this was so that the SimpleRest.Core assembly did not start getting polluted with code that did not concern the core SimpleRest pipeline functionality. Because SimpleRest.Core provides many extensibility points SimpleRest.Core.Extensions can plug into those and provide additional value to developers such as automatic XSD route creation for each registered service and operation.
Examples in downloadable documentation
Manually register individual services using event arguments using
Examples in downloadable documentation
Examples in downloadable documentation
Dependency injection can be accomplished very easily by setting a property on the associated service Configuration object called CreateServiceInstance. CreateServiceInstance is always called when an instance of a service needs to be created. This method provides the service type that needs to be created and allows for IoC containers to be used therein.
Example in downloadable documentation
There are two ways in which error handling can be accomplished using the SimpleRest pipeline. The global way to handle all errors for a service is done by setting the ErrorHandler property on the Configuration object for an associated service. All unhandled errors that occur during the SimpleRest request lifecycle will be funneled through this handler. The error handler gives the developer visibility into the actual exception that was thrown, the http request, and the http response. The developer can set response information for the content body, response headers, and status code here.
Example in downloadable documentation
Another way a developer can handle errors is on the service level itself rather than a global handler. This is accomplished by inheriting SimpleRest.Core.Routing.ServiceBase on the associated service and overriding the OperationExecutionException method. Visibility into the exception and the associated operation will be provided here and handling of the exception can occur. It is important to understand that even though the error is handled here it will still be bubbled up to the ErrorHandler as well.
Example in downloadable documentation
When a service inherits SipelRest.Core.Routing it provides visibility into service specific operation execution. It allows the developer to override three methods: OperationPreExecution, OperationPostExecution, and OperationExecutionException. OperationPreExecution is a method that is invoked before any operation is invoked on that service giving visibility into the operation that is about to be invoked. OperationPostExecution is a method that is after any operation is invoked on that service giving visibility into the operation that was invoked the value that is being returned. The OperationExecutionException method is invoked in the event an operation throws an exception and gives visibility into the operation as well as the System.Exception that was thrown. In the event a developer handles the OperationExecutionException it is important to know that the global ErrorHandler wired up for that service will still be invoked.
Inheriting this class on a service gives visibility into which operations have been registered for the service and pieces of metadata. This was done in the event the developer needed this information for any sort of reason. This property is called RegisteredOperations and is read only.
Because creating an instance of a service at runtime can be taxing for every single request this class gives the developer the opportunity to set a flag called IsReusable. When this flag is set to true the SimpleRest pipeline will create a single instance of this service and cache it at the application level so that the next call to this service is pulled from cache instead of being instantiated.
How would a developer allow for a custom complex type as an input parameter to the service operations? It makes sense that there would be a way to handle this scenario so that creating this custom complex type is done in a single place rather than riddled throughout the code polluting it.
When this class is inherited it gives the developer the opportunity to specify Operation Mapping Handlers by calling the AddMapping method. This allows a developer to create functionality to map custom complex objects they create into input parameters
for the service operations.
To do this the developer creates a class and either inherits SimpleRest.Core.Routing.OperationMappingHandler or extends SimpleRest.Core.routing.IOperationMappingHandler. These provide the developer with visibility into the http request and the operation
being invoked in which they can use to formulate the complex object they wish to pump into the service operation. The OutputParameterName is very important as this indicates what the input parameter name should be on the operation in which the object
should be mapped.
Example in downloadable documentation