- PVSM.RU - https://www.pvsm.ru -

Начинаем делать RESTful web-сервисы на WCF и Nelibur

WCF — реально мощная штука, но раз за разом для новых проектов мы вынуждены создавать новые, похожие друг на друга веб-сервисы. В этой статье (переводе) мы увидем, как создать повторно используемый веб-сервис с помощью Nelibur [1]. Nelibur — это Message based web service framework на чистом WCF. Давайте посмотрим, как начать создание web-сервисов на WCF с использованием Nelibur.

Шаг 1. Создание приложения

Для простоты хостить WCF-сервис будет консольное приложение. Так что просто добавляем новый консольный проект.
Начинаем делать RESTful web сервисы на WCF и Nelibur

Шаг 2. Инсталлируем Nelibur

Самый простой способ установить Nelibur — воспользоваться NuGet package manager [2].
Начинаем делать RESTful web сервисы на WCF и Nelibur

То же самое можно сделать с помощью Package Manager Console [2]
Начинаем делать RESTful web сервисы на WCF и Nelibur

Теперь мы готовы создать RESTful WCF message based сервис.

Шаг 3. Создаем WCF-сервис

Для примера, возмем следующие требования к WCF-сервису:

  • InstanceContextMode [3] должен быть PerCall
  • ResponseFormat должен быть Json

Nelibur уже содержит нужную нам реализацию: JsonServicePerCall [4].
Итак, добавляем код запуска нашего сервиса.

internal class Program
{
    private static WebServiceHost _service;

    private static void Main()
    {
        _service = new WebServiceHost(typeof(JsonServicePerCall));
        _service.Open();

        Console.WriteLine("ShipTrackingService is running");
        Console.WriteLine("Press any key to exitn");

        Console.ReadKey();
        _service.Close();
    }
} 

Прописываем конфигурацию

<system.serviceModel>
    <services>
        <service name="Nelibur.ServiceModel.Services.Default.JsonServicePerCall">
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:9095/ShipTrackingService" />
                </baseAddresses>
            </host>
            <endpoint binding="webHttpBinding"
                        contract="Nelibur.ServiceModel.Contracts.IJsonService" />
        </service>
    </services>
</system.serviceModel>

Реализуем бизнес-логику

Наш сервис должен уметь:

  • Добавлять корабль
  • Получать корабль по ShipId

Создаем команду AddShipCommand

public sealed class AddShipCommand
{
    public string ShipName { get; set; }
} 

Результатом выполнения команды должен стать объект ShipInfo

public sealed class ShipInfo
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

Добавляем запрос ShipLocationQuery, результатом выполнения которого должен быть объект ShipLocation

public sealed class ShipLocationQuery
{
    public Guid ShipId { get; set; }
}
 
public sealed class ShipLocation
{
    public string Location { get; set; }
    public Guid ShipId { get; set; }
}

Теперь нам нужно сделать обработчик команды и запроса

public sealed class ShipProcessor : IPost<AddShipCommand>,
                                    IGet<ShipLocationQuery>
{
    private static readonly Dictionary<Guid, Ship> _ships = new Dictionary<Guid, Ship>();

    public object Get(ShipLocationQuery request)
    {
        if (_ships.ContainsKey(request.ShipId))
        {
            return new ShipLocation
            {
                Location = "Sheldonopolis",
                ShipId = request.ShipId
            };
        }
        throw new WebFaultException(HttpStatusCode.BadRequest);
    }

    public object Post(AddShipCommand request)
    {
        var ship = new Ship(request.ShipName, Guid.NewGuid());
        _ships[ship.Id] = ship;
        return new ShipInfo
        {
            Id = ship.Id,
            Name = ship.Name
        };
    }
} 

Связываем команду и запрос с обработчиком

internal class Program
{
    private static WebServiceHost _service;

    private static void ConfigureService()
    {
        NeliburRestService.Configure(x =>
        {
            x.Bind<AddShipCommand, ShipProcessor>();
            x.Bind<ShipLocationQuery, ShipProcessor>();
        });
    }

    private static void Main()
    {
        ConfigureService();

        _service = new WebServiceHost(typeof(JsonServicePerCall));
        _service.Open();

        Console.WriteLine("ShipTrackingService is running");
        Console.WriteLine("Press any key to exitn");

        Console.ReadKey();
        _service.Close();
    }
}

Все, сервис закончен. Как вы заметили, вы можете добавлять любые операции без изменения WCF-сервиса…

Клиент, использующий наш WCF-сервис

В качестве клиента можно использовать:

Fiddler

Добавление нового корабля (с помощью POST-запроса):
Начинаем делать RESTful web сервисы на WCF и Nelibur

Получение корабля по ShipId (с помощью GET-запроса):
Начинаем делать RESTful web сервисы на WCF и Nelibur

JsonServiceClient

Для создания своего клиента — добавляем еще одно консольное приложение.
Вот код клиента:

internal class Program
{
    private static void Main()
    {
        var client = new JsonServiceClient(Settings.Default.ServiceAddress);
        var shipInfo = client.Post<ShipInfo>(new AddShipCommand { ShipName = "Star" });
        Console.WriteLine("The ship has added: {0}", shipInfo);

        var shipLocation = client.Get<ShipLocation>(new ShipLocationQuery { ShipId = shipInfo.Id });
        Console.WriteLine("The ship {0}", shipLocation);

        Console.ReadKey();
    }
} 

Запускаем наш клиент и видим результат выполнения:

На стороне сервиса
Начинаем делать RESTful web сервисы на WCF и Nelibur

На стороне клиента
Начинаем делать RESTful web сервисы на WCF и Nelibur

Дополнительная литература

Вот и все

Я надеюсь, вам понравилось. Спасибо за чтение статьи (перевода).
Исходники можно скачать с оригинала [11].

Автор: Truba

Источник [12]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/net/61513

Ссылки в тексте:

[1] Nelibur: http://nelibur.org/

[2] NuGet package manager: http://docs.nuget.org/docs/start-here/using-the-package-manager-console

[3] InstanceContextMode: http://msdn.microsoft.com/en-us/library/system.servicemodel.instancecontextmode.aspx

[4] JsonServicePerCall: https://github.com/Nelibur/Nelibur/blob/master/Source/Nelibur/ServiceModel/Services/Default/JsonServicePerCall.cs

[5] Fiddler: http://www.telerik.com/fiddler

[6] Rest Console: https://chrome.google.com/webstore/detail/rest-console/cokgbflfommojglbmbpenpphppikmonn?hl=en

[7] JsonServiceClient : https://github.com/Nelibur/Nelibur/blob/master/Source/Nelibur/ServiceModel/Clients/JsonServiceClient.cs

[8] What is a message based web service?: https://github.com/ServiceStack/ServiceStack/wiki/What-is-a-message-based-web-service%3F

[9] Advantages of message based web services: https://github.com/ServiceStack/ServiceStack/wiki/Advantages-of-message-based-web-services

[10] Построение RESTful Message Based веб-сервисов на WCF: http://habrahabr.ru/post/218149/

[11] оригинала: http://www.codeproject.com/Articles/780654/Getting-started-with-RESTful-WCF-powered-by-Nelibu

[12] Источник: http://habrahabr.ru/post/225117/