Interfaces

Project

Pages Restful

NuGet packageOwin.Framework.Pages.Restful
GitHub sourceOwinFramework.Pages.Restful

Home |  Readme

Allows you to add REST endpoints to a website using classes and methods decorated with attributes

This package contains a Build Engine for services. If you want the fluent builder to use this build engine you need to add a couple of lines to your startup code similar to:

    var fluentBuilder = ninject.Get<IFluentBuilder>();
    ninject.Get<OwinFramework.Pages.Restful.BuildEngine>().Install(fluentBuilder);
The assumes that you are using Ninject as your IoC container, and followed the getting started walkthrough. If this is not the case then you will need to adjust the code to work in your application.

After adding this build engine to the fluent builder you can add web services to your application by writing classes that are decorated with attributes. The fluent builder will discover these classes and use the attributes to configure these services.

Sample Service

The code below is taken from one of the sample applications. It is a service that exposes 4 endpoints that add, subtract, multiply and divide two numbers.

You can invoke this service by typing a URL into a browser similar to http://mycompany.com/math/add?a=45&b=76.

using System;
using System.Collections.Generic;
using OwinFramework.Pages.Core.Attributes;
using OwinFramework.Pages.Core.Enums;
using OwinFramework.Pages.Restful.Interfaces;

namespace Sample1.SampleServices
{
    [IsService("arithmetic", "/math/", new[] { Method.Get })]
    public class ArithmeticService
    {
        [Endpoint]
        [EndpointParameter("a", typeof(double))]
        [EndpointParameter("b", typeof(double))]
        public void Add(IEndpointRequest request)
        {
            var a = request.Parameter<double>("a");
            var b = request.Parameter<double>("b");
            request.Success(a + b);
        }

        [Endpoint]
        [EndpointParameter("a", typeof(double))]
        [EndpointParameter("b", typeof(double))]
        public void Subtract(IEndpointRequest request)
        {
            var a = request.Parameter<double>("a");
            var b = request.Parameter<double>("b");
            request.Success(a - b);
        }

        [Endpoint]
        [EndpointParameter("a", typeof(double))]
        [EndpointParameter("b", typeof(double))]
        public void Multiply(IEndpointRequest request)
        {
            var a = request.Parameter<double>("a");
            var b = request.Parameter<double>("b");
            request.Success(a * b);
        }

        [Endpoint]
        [EndpointParameter("a", typeof(double))]
        [EndpointParameter("b", typeof(double))]
        public void Divide(IEndpointRequest request)
        {
            var a = request.Parameter<double>("a");
            var b = request.Parameter<double>("b");
            request.Success(a / b);
        }
    }
}
When writing services you must ensure that the data types produced by the parameter validator are of the same type as requested by your code. In the example above all parameters are declared as double and retrieved as double in the code.

Attributes

The class that defines your service must be decorated with an [IsService()] attribute as shown in the example above.

Your class can contain any number of methods. Any or all of these methods can be exposed as REST endpoints by decorating the method with an [Endpoint()] attribute. These methods can be executed by sending Httl requests to your website.

Methods decorated with the [Endpoint()] attribute must have a return type of void and the first argument must be of type IEndpointRequest. Other arguments are optional as described below.

Endpoint methods can optionally be decorated with one or more [EndpointParameter()] attributes to define the parameters that can be passed to the method. These attributes also define the mechanisms that are supported for parameter passing and the parameter parser to use.

Endpoint methods can optionally have additional arguments and these arguments can be decorated with [EndpointParameter()] attributes to define how parameters passed in the Html request are bound to those method arguments.

The two endpoints below will function identically to the caller of the Http endpoint. The first version produces slightly better API documentation and is the recommended syntax, but you can also use the second version of the syntax if you prefer.

[Endpoint]
[EndpointParameter("a", typeof(double))]
[EndpointParameter("b", typeof(double))]
public void Add(IEndpointRequest request)
{
    var a = request.Parameter<double>("a");
    var b = request.Parameter<double>("b");
    request.Success(a + b);
}
[Endpoint]
public void Add(
    IEndpointRequest request,
    [EndpointParameter] double a,
    [EndpointParameter] double b)
{
    request.Success(a + b);
}

Supported Features

This service builder supports the following features:

  • A root path is usually specified for the service. By default the method name will be used as a sub-path below this root. The URL is not case sensitive. You can override the default path to an endpoint by passing a parameter to the [Endpoint()] attribute. This endpoint path can be relative to the service root or an absolute path within the website.
  • The service can be configured to only process requests with certain methods and pass on any other requests to the rest of the routing chain. For example you might only want to handle POST requests in the service and allow GET requests for the same URL to pass through to the page rendering.
  • You can define a permission that the calling identity must have to be allowed to call this service and optionally restrict access further by passing the service/method name as a resource path when checking permissions. You can also override the service settings on each endpoint.
  • You can specify a request deserializer and a response serializer for the service, and you can override this for each service endpoint. If you do not specify these then they default to Json using the NewtonSoft library.
  • Endpoint parameter attributes define the name of the parameter and the parser to use. The parser is specified as a Type. This Type can be a value type like int or double which makes the parameter required, or it can be a nullable type like int? which makes the parameter optional but when present must be of the specified type.
  • For the endpoint parameter parser you can also supply a Type that implements IParameterParser. A few parsers are provided with this package. You can also write your own parser containing your application logic, custom documentation and custom error messages.
  • Endpoint parameter attributes also define the methods that the caller can use to pass the parameter. The default is to only allow parameters in the query string, but you can have any combination of: query string, custom header form field or path element. When parameters are passed as path elements the url of the service must contain placeholders for the parameters. These placeholders are the parameter name in curly braces - for example "/myservice/mymethod/{param1}/{param2}".

For more details on how to take advantage of these features, click the links below: