View on GitHub

EasyPeasy

JAX-RS style REST Client for .Net

Download this project as a .zip file Download this project as a tar.gz file

Welcome to EasyPeasy.

EasyPeasy is a .NET REST client that takes the JAX-RS annotation based approach to describe a RESTful service, where interfaces are used to describe the service endpoints.

A number of attributes are used to decorate both the interface and the method definitions, and from this, EasyPeasy will generate an implementation of the client for you!

Example

[Path("/services/customers"), 
 Consumes("application/json"), 
 Produces("application/json")] 
public interface ICustomerService
{
    // Built in support for async requests
    [GET, Path("/{name}")]
    Task<Customer> GetCustomerAsync(
        [PathParam("name")] string name);

    // Synchronous equivalent
    [GET, Path("/{name}")]
    Customer GetCustomer(
        [PathParam("name")] string name);

    [DELETE, Path("/{name}")]
    void DeleteCustomer(
        [PathParam("name")] string name, 
        [QueryParam("q")] bool q);

    [DELETE, Path("/{name}")]
    Task DeleteCustomerAsync(
        [PathParam("name")] string name,
        [QueryParam("q")] bool q);
}

The proxy type can then be created simply by calling:


IEasyPeasyFactory factory = new EasyPeasyFactory();
ICustomerService client = 
    factory.Create<ICustomerService>(
        new Uri("http://server.com"));
Customer customer = client.GetCustomer("My Customer");

Using MEF:


AssemblyCatalog catalog = new AssemblyCatalog(typeof(IEasyPeasyFactory).Assembly);
CompositionContainer container = new CompositionContainer(catalog);
IEasyPeasyFactory factory = container.GetExportedValue();

ICustomerService client = 
    factory.Create<ICustomerService>(
        new Uri("http://server.com"));
Customer customer = client.GetCustomer("My Customer");

The following attributes are supported:

In addition, further attributes to method parameters to pull information out of the request are available. All the *Param attributes take a key of some form which is used to look up the value required.

How it works

The ServiceProxy class uses reflection to scoop up information on the type you give it. Reflection.Emit is then used to lovingly craft a new class to implement your interface. The new class extends ServiceClient where most of the work takes place.

Each implemented method on the interface simply generates a new MethodMetadata object which describes the method based on the method arguments, and the attributes associated to it.

Task Aware

Service calls are asynchronous in nature, so it is only natural for methods to be described in this way. The proxy generator will look for methods that return Tasks and generate the appropriate implementation using async methods. In fact, non Task based return types still use tasks under the hood, they just block until they return.

Authors and Contributors

Currently the project has a single author, Matt Channer (@mattchanner).