Fork me on GitHub

Getting started Edit on GitHub


Here we will guide you through the steps needed to create a very basic Pomona service.

This example is also available in the Pomona repository in the samples/Pomona.Samples.DustyBoxes1 folder of the Pomona source.

Installing

We start by creating a new C# console project and install the Pomona NuGet package from the standard NuGet feed.

PM> Install-Package Pomona

Note: We make a command line project so we can run this as a self-hosted Nancy host. In a real life example we would probably use another type of project.

The domain model

Now that we have a empty project we need some domain model to expose.


    public class GameConsole
    {
        public string Id { get; set; }
        public string Name { get; set; }
    }

Every resource must have an id, which will be used as part of the URL.

Setting up a module

Then we need to create a module, which represents the endpoint of our service.


    [PomonaConfiguration(typeof(DustyConfiguration))]
    public class DustyModule : PomonaModule
    {
    }

Additionally we need a corresponding configuration class.


    public class DustyConfiguration : PomonaConfigurationBase
    {
        public override IEnumerable<object> FluentRuleObjects => new object[] { new DustyRules() };
        public override IEnumerable<Type> SourceTypes => new[] { typeof(GameConsole) };

        public class DustyRules
        {
            public void Map(ITypeMappingConfigurator<GameConsole> gameConsole)
            {
                gameConsole.HandledBy<GameConsoleHandler>();
            }
        }
    }

The configuration above have two properties overridden.

  • FluentRuleObjects returns a list containing one rule object DustyRules, which will be scanned for mapping rules.
  • SourceTypes returns a list of the domain objects to be mapped.

Handling resource requests

In the Map method of the DustyRules we defined that GameConsoleHandler will handle requests for the GameConsole resource.

This is a handler class, which will handle HTTP actions for one or more resources. We can now implement GameConsoleHandler, like this:


    public class GameConsoleHandler
    {
        public IQueryable<GameConsole> Query()
        {
            return
                new[]
                {
                    new GameConsole() { Id = "a2600", Name = "Atari 2600" },
                    new GameConsole() { Id = "gameboy", Name = "Game Boy" },
                    new GameConsole() { Id = "nes", Name = "Nintendo Entertainment System" },
                }.AsQueryable();
        }
    }

For exposing a read-only collection of resources we just need to define one method returning an IQueryable<GameConsole>.

Usually you would proabably use a LINQ provider here, like the one in NHibernate or Entity Framework. But for now we'll just use an in-memory array.

Running the service

At this point our project should contain the following classes:

  • GameConsole - Our domain object
  • GameConsoleHandler - Handler for GameConsole
  • DustyConfiguration - Configuration for Pomona module
  • DustyModule - The Pomona module
  • Program - The console app startup class

As mentioned earlier we will be using Nancy self host for this example. For this the package Nancy.Hosting.Self must be installed from the NuGet gallery.

PM> Install-Package Nancy.Hosting.Self

We also need to modify our Progam.cs file to actually bootstrap and fire up a local http server.


    class Program
    {
        static void Main(string[] args)
        {
            var baseUri = new Uri("http://localhost:1337");
            var nancyHost =
                new NancyHost(new HostConfiguration()
                {
                    // To show annoying UAC dialog in windows when not running as admin
                    UrlReservations = new UrlReservations() { CreateAutomatically = true }
                }, baseUri);
            nancyHost.Start();

            // Automatically launch web browser
            Process.Start(baseUri.ToString());

            Console.WriteLine($"Starting server on {baseUri}, press enter to stop..");
            Console.ReadLine();
            nancyHost.Stop();
        }
    }

Now our example should be able to compile, run and be explored at http://localhost:1337.

$ curl http://localhost:1337 -H "Accept: application/json"
{
  "game-consoles": "http://localhost:1337/game-consoles"
}
C:\>curl http://localhost:1337/game-consoles -H "Accept: application/json"
{
  "_type": "__result__",
  "totalCount": -1,
  "items": [
    {
      "_uri": "http://localhost:1337/game-consoles/a2600",
      "id": "a2600",
      "name": "Atari 2600"
    },
    {
      "_uri": "http://localhost:1337/game-consoles/gameboy",
      "id": "gameboy",
      "name": "Game Boy"
    },
    {
      "_uri": "http://localhost:1337/game-consoles/nes",
      "id": "nes",
      "name": "Nintendo Entertainment System"
    }
  ],
  "skip": 0,
  "previous": null,
  "next": null
}

And there you have it, congratulations, you have just completed our little tutorial. Read the following chapters of the documentation for further experimentation,