Serviços Web do .NET

Criando serviços Web entre plataformas com o ServiceStack

Ngan Le

Baixar o código de exemplo

Eu gosto de trabalhar com o Windows Communication Foundation (WCF) porque há excelente suporte para o framework em Visual Studio. Acho que é bastante fácil de construir um serviço WCF Web do zero e obter-se e correr no meu ambiente de desenvolvimento sem instalar redistribuíveis e ferramentas adicionais. Falarei sobre minhas experiências com o desenvolvimento da cruz-plataforma aqui, então você pode ser interessado neste artigo se aplicam-se as seguintes afirmações:

  • Você já está familiarizado com o WCF e c#.
  • Você precisa construir um cruz-plataforma Web serviço.

Acho que todos concordamos que escrever aplicativos multi-plataforma é no mínimo uma inconveniência, mas às vezes é inevitável. Se você for como mim — Windows-limite e investiu pesadamente em c# — montando um serviço de Web de plataformas pode acarretar uma sobrecarga significativa. Isso inclui reconfigurando seu ambiente de computação amado Windows para acomodar um diferente conjunto de ferramentas de desenvolvimento e aprendizagem possivelmente ainda outra linguagem de programação. Neste artigo, mostrarei como você pode aproveitar a semelhança do WCF de ServiceStack (um framework open source .NET e Mono REST Web services) para realizar tal tarefa, sem nunca deixar o Visual Studio ou para o ambiente Microsoft .NET Framework.

Sobre serviços da Web

Um típico serviço Web é colocado para fora como retratado no Figura 1.

A Typical Web Service Layout
Figura 1 Layout de serviço Web típica

A camada de serviço é onde você definir sua interface de serviço Web. Esta é a única camada com o qual o cliente precisa interagir para consumir o Web service.

A camada de negócios é geralmente pesada com a lógica de negócios, obviamente. Isto é onde reside a carne de sua implementação de serviço Web, mantendo a sua luz de camada de serviço e com foco em contratos de cliente/servidor e comunicação.

Destina-se a camada de dados para encapsular o acesso a dados e fornecer modelos de dados captada para manipulação na camada de negócios.

Neste artigo, vou me concentrar na camada de serviço.

Objetos de transferência de chamadas de procedimento remoto versus dados

Alguns serviços da Web usar a abordagem de Remote Procedure Call (RPC), onde cada pedido é projetado para se assemelhar a uma chamada de função:

public interface IService {
  string DoSomething(int input);
}

A abordagem RPC tende a fazer o serviço da Web mais suscetíveis à interface alterações significativas. Por exemplo, no trecho de código anterior, se uma versão posterior do serviço da Web requer duas entradas do cliente para executar o método DoSomething — ou precisa retornar a outro campo, além do valor de seqüência de caracteres — uma alteração de quebra para os antigos clientes é inevitável. Claro, você sempre pode criar um método de DoSomething_v2 paralelo para levar dois argumentos de entrada, mas ao longo do tempo que ia atravancar seu Web service interface e risco de confusão do seu consumidor, antigos e novos.

Definindo interfaces de serviço Web voltadas para o modelo de objeto de transferência de dados (DTO) favorece a sabedoria convencional. O código a seguir mostra como o método Web DoSomething pode ser transformado em modelo de DTO:

public class DoSomethingRequest {
  public int Input { get; set; }
}
public class DoSomethingResponse {
  public string Result { get; set; }
}
public interface IService {
  DoSomethingResponse DoSomething(DoSomethingRequest request);
}

Na sequência desta escola de pensamento, cada método Web leva uma única solicitação DTO e retorna uma resposta única DTO. A idéia é que, adicionar novos campos ao pedido DTO e resposta DTO não quebrará os clientes mais antigos.

É interessante notar que tanto o estilo RPC e o DTO-estilo Web interfaces de serviço são suportados pelo WCF, mas ServiceStack só suporta o estilo DTO. ServiceStack abraça o princípio do estilo DTO remoto de interfaces de serviço da Web, para menos falação e mais chunkiness no design de interface Web serviço. Esta é a chave para a compreensão ServiceStack, porque o quadro é projetado em uma maneira que reforça o princípio.

O que é ServiceStack?

Como mencionado, a ServiceStack é uma fonte aberta, cruz-plataforma Mono Web service framework, e está ganhando popularidade. Serviços da Web criados com ServiceStack podem executar em um ambiente Windows com código .NET ou em um ambiente Linux com suporte a Mono. Os sistemas operacionais suportados pelo Mono incluem:

  • Linux
  • Mac OS X, iOS
  • Sun Solaris
  • BSD
  • Microsoft Windows
  • Nintendo Wii
  • Sony PlayStation 3

Para obter mais informações sobre as plataformas suportadas pelo Mono, consulte mono-project.com/Supported_Platforms.

Se você gosta de trabalhar com o .NET Framework e WCF e necessitam de Implantando seus serviços Web .NET em um ambiente que não seja Windows, ServiceStack é uma opção ideal. Devido à semelhança de ServiceStack e WCF, a transição de um para o outro requer um ajuste pequeno em termos de ambiente de desenvolvimento e ferramentas. Você vai continuar escrevendo código c# dentro do Visual Studio.

ServiceStack impõe remotos serviço melhores práticas, com base em Convenção DTO padrões Web para sua interface de serviço Web, enquanto a WCF deixa a definir livremente uma API de serviços Web, como você vê o ajuste. ServiceStack também fornece um objeto de status de resposta de out-of-the-box que pode ser usado para compor a resposta DTO, incentivando um esquema de manipulação de erro mais direto e simplista. Embora isto pode facilmente ser implementado com WCF, não é uma rota óbvia. Versões recentes do ServiceStack também fornecem um mecanismo de manipulação de erro de exceção com base em que é semelhante ao — embora não tão sophis­cional como — WCF baseados em culpa manipulação de erro através de contratos de culpa.

As normas impostas pelo ServiceStack são facilmente implementadas no WCF com um pouco de digitação extra. No entanto, além de portabilidade, ServiceStack é uma opção viável para construir um serviço Web RESTful porque estabelece convenções que simplificam o URI HTTP roteamento. Ao mesmo tempo, ServiceStack as forças cada solicitação de serviço da Web para ser implementado em uma classe separada, promovendo uma natural separação de preocupações para um modelo de serviço RESTful.

ServiceStack também oferece outras vantagens, tais como log out-of-the-box e utilitário de validação de dados básicos. Você pode ler mais sobre ServiceStack em servicestack. NET.

Este artigo pressupõe que você tenha alguma familiaridade com o WCF e o .NET Framework. Para melhor demonstrar como os conceitos WCF podem traduzir a ServiceStack conceitos, implementarei primeiro a camada de serviço no WCF. Em seguida, mostrarei como transformar o serviço WCF da Web em um serviço da Web entre plataformas por portá-lo a um serviço de Web equivalente usando ServiceStack.

Criando um serviço Web do WCF simples

Para demonstrar como ServiceStack pode servir como um substituto para o WCF em um ambiente multiplataforma, vou começar com um simples serviço do WCF Web.

O serviço da Web é um sistema de bilhética trivial restaurante chamado TicketService que implementa o contrato de serviço a seguir:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

O TicketService permite que seus clientes para um novo bilhete na fila, puxe um bilhete para fora da fila e recuperar um inventário completo de todos os bilhetes atualmente na fila.

O serviço da Web consiste em três projetos do Visual Studio , como mostrado na Figura 2(executando a minha solução de amostra, que pode ser baixada em archive.msdn.microsoft.com/mag201308Services, exige Visual Studio 2012 com ferramentas para desenvolvedores Web e o .NET Framework 4.5).

WCF Ticket Service Visual Studio Projects
Figura 2 bilhetes WCF serviço Visual Studio projetos

Os três projetos são brevemente descritos como segue:

  • O projeto TicketSystem.ServiceContract é onde a interface do serviço é definida.
  • O projeto de TicketSystem.TicketProcessor contém os detalhes de implementação da lógica de negócios de serviço Web. Este projeto não contém nenhuma referência ao WCF.
  • O projeto WcfServer implementa o bilhete­System.ServiceContracts e anfitriões Web serviço no IIS.

Também juntei um cliente WCF para consumir o TicketService. O cliente do WCF é um aplicativo de console que usa código gerado a partir da adição de uma referência de serviço WCF para o TicketService para se comunicar com o serviço da Web usando SOAP sobre IIS. Aqui é a implementação de console do cliente:

static void Main(string[] args) {
  Console.Title = "WCF Console Client";
  using (TicketServiceClient client = new TicketServiceClient()) {
    Ticket[] queuedTickets = client.GetAllTicketsInQueue();
    foreach (Ticket ticket in queuedTickets) {
      PrintTicket(ticket);
    }
  }
}

A implementação do código de cliente serve-se as informações mostradas na Figura 3.

The WCF Console Client
Figura 3 o cliente de Console do WCF

Construindo um serviço da Web de ServiceStack equivalente

Pré-requisitos para trabalhar com ServiceStackpara trabalhar com ServiceStack, primeiro você deve baixar os redistribuíveis. A maneira mais fácil de fazer isto é através da exten NuGet Visual Studio ­sion que permite que você facilmente instalar e atualizar as ferramentas e bibliotecas de terceiros. Você pode baixar e instalar o cliente do NuGet de nuget.codeplex.com. Depois NuGet é instalado, você deve ver no Visual Studio menu itens mostrados em Figura 4.

The NuGet Package Manager Console in Visual Studio
Figura 4 o NuGet Gerenciador de Pacotes Console no Visual Studio

Agora eu vou fazer uma passo a passo passo a passo sobre como criar um serviço Web de ServiceStack que é o equivalente do serviço WCF Web que construí anteriormente.

Primeiro, dar o exemplo de serviço WCF Web como ponto de partida. Em seguida retire o WcfClient e os WcfServer projetos da solução. Estes projetos são específicos para o WCF, e vai ser substituídos com projetos compatíveis com o ServiceStack mais tarde.

Na janela do Console de Gerenciador de Pacotes , selecione o projeto TicketSystem.ServiceContract. No prompt de comando, digite "install-pacote ServiceStack", como mostrado na Figura 5.

Installing ServiceStack Redistributables with NuGet Package Manager
Figura 5 instalando ServiceStack Redistributables com NuGet Gerenciador de Pacotes

Esta etapa downloads mais recentes redistribuíveis necessários para construir um serviço da Web do .NET usando ServiceStack. Os redistribuíveis são encenados sob um nome de pasta "Pacotes" colocados em sua pasta de raiz de solução de Visual Studio . Além disso, as referências DLL são adicionadas para o projeto de TicketSystem.ServiceContract. Junto com isso é um packages.config arquivo criado na pasta raiz do projeto, fornecendo-lhe informações de versão e tempo de execução para cada DLL de ServiceStack:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="ServiceStack" version="3.9.46" 
    targetFramework="net45" />
  <package id="ServiceStack.Common” version=“3.9.46”
    targetFramework="net45" />
  <package id="ServiceStack.OrmLite.SqlServer" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Redis" version="3.9.45"
    targetFramework="net45" />
  <package id="ServiceStack.Text" version="3.9.46"
    targetFramework="net45" />
</packages>

Em seguida, converta os contratos de dados do WCF definidos no projeto TicketSystem.ServiceContract para algo que ServiceStack pode entender.

Converter contratos de dados do WCF para contratos de dados ServiceStack WCF usa contratos de dados para estabelecer os meios de comunicação entre o cliente e o servidor. ServiceStack faz o mesmo. WCF requer que os atributos apropriados são colocados em qualquer objeto de dados e membro de dados que você deseja serializar e enviar sobre o fio; caso contrário, o WCF simplesmente ignora-los. Isto é onde ServiceStack e WCF diferem. ServiceStack irá serializar todas Plain Old CLR Objects (POCOs) referenciado no contrato de serviço e torná-los visíveis ao lado do cliente. Seguir são WCF e representações de código de ServiceStack do mesma bilhete dados contrato referência na interface TicketService.

Aqui é o WCF <Ticket> contrato de dados:

[DataContract]
public class Ticket {
  [DataMember]
  public int TicketId { get; set; }
  [DataMember]
  public int TableNumber { get; set; }
  [DataMember]
  public int ServerId { get; set; }
  [DataMember]
  public List<Order> Orders { get; set; }
  [DataMember]
  public DateTime Timestamp { get; set; }
}

Aqui é o ServiceStack <Ticket> contrato de dados:

public class Ticket {
  public int TicketId { get; set; }
  public int TableNumber { get; set; }
  public int ServerId { get; set; }
  public List<Order> Orders { get; set; }
  public DateTime Timestamp { get; set; }
}

A principal diferença entre o serviço­pilha e WCF no que diz respeito a interface do serviço é que ServiceStack coloca restrições adicionais sobre a interface do serviço. ServiceStack dita que cada solicitação original é identificada por um objeto de pedido único, porque não há nenhum conceito de uma operação de serviço Web"" (ou seja, nome do método) no mundo de ServiceStack. Isto significa que você não pode reutilizar uma solicitação DTO, através de várias implementações de serviço com ServiceStack. Todos os contratos de operação de serviço ServiceStack Web equivaleria a algo semelhante para os seguintes contratos de serviço WCF:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue(GetAllTicketsInQueueRequest request);
  [OperationContract]
  void QueueTicket(QueueTicketRequest request);
  [OperationContract]
  Ticket PullTicket(PullTicketRequest request);
}

O código anterior é nada mais do que a interface do serviço RPC-estilo TicketService WCF original mostrado aqui, mas transformou-se para abraçar a Convenção DTO:

[ServiceContract]
public interface ITicketService {
  [OperationContract]
  List<Ticket> GetAllTicketsInQueue();
  [OperationContract]
  void QueueTicket(Ticket ticket);
  [OperationContract]
  Ticket PullTicket();
}

Aqui é o equivalente TicketService ServiceStack interface de serviço:

public class GetAllTicketsInQueueRequest {}
public class QueueTicketRequest {
  public Ticket Ticket { get; set; }
}
public class PullTicketRequest {}
public interface ITicketService {
  List<Ticket> Any(GetAllTicketsInQueueRequest request);
  void Any(QueueTicketRequest request);
  Ticket Any(PullTicketRequest request);
}

ServiceStack oferece suporte a diferentes ações, como qualquer um, Get e Post. As escolhas que você faz aqui apenas impacto solicitações HTTP. Especificando qualquer sobre uma solicitação de serviço da Web significa que a operação pode ser invocada por um HTTP GET e um HTTP POST. Esta aplicação simplifica a implementação do serviço Web RESTful, que está além do escopo deste artigo. Para transformar seu serviço da Web de ServiceStack em um serviço Web RESTful, basta adicionar a URL [Route(...)]  atributos de suas declarações de solicitação de serviço da Web.

Criar um serviço de Web hospedado ServiceStack ASP.NET agora que você tem a interface de serviço Web definida para seu serviço da ServiceStack Web, é hora de implementá-lo e obtê-lo lançado.

Primeiro, adicione um aplicativo da Web vazio de ASP.NET . Isto é como eu escolhi para hospedar meu serviço ServiceStack Web para sua conveniência. Não é o único método para um serviço Web construído na ServiceStack de hospedagem. Você também pode hospedar um serviço dentro de um serviço do Windows ou na forma de um aplicativo de console em execução em um servidor Web, ou até mesmo independente de um.

O nome deste projeto de Visual Studio ServiceStackServer. É o equivalente do projeto WcfServer no exemplo de código de serviço WCF.

Use o Console do Gerenciador de Pacotes NuGet para adicionar referências de ServiceStack para ServiceStackServer, como mostrado na Figura 6.

Add ServiceStack Library References to the ServiceStackServer Project
Figura 6 Adicionar biblioteca ServiceStack referências para o projeto de ServiceStackServer

Agora você tem o que você precisa implementar a interface ITicketService. A classe TicketService deve estender o ServiceStack.Service­Interface.Service classe fornecida pela estrutura, como este:

public class TicketService : ServiceStack.ServiceInterface.Service,
  ITicketService {
  public List<Ticket> Any(GetAllTicketsInQueueRequest request) {
    // Implement ...
}
  public void Any(QueueTicketRequest request) {
    // Implement ...
}
  public Ticket Any(PullTicketRequest request) {
    // Implement ...
}
}

Tudo o resto é o mesmo que a execução do WCF.

Em seguida, adicione uma classe de aplicativo Global chamado global. asax para o projeto de ServiceStackServer, como mostrado na Figura 7. Isto é onde você inicializar seu aplicativo da Web ASP.NET .

Add Global.asax to ServiceStackServer
Figura 7 adicionar global. asax para ServiceStackServer

Você é obrigado a herdar o ServiceStack.WebHost.End­pontos.Classe de AppHostBase se você quiser hospedar seu serviço da Web dentro de uma aplicação ASP.NET . Consulte a Figura 8 para obter um exemplo.

Figura 8 hospeda um serviço de Web ServiceStack dentro ASP.NET

public class Global : System.Web.HttpApplication {
  public class TicketServiceHost : 
    ServiceStack.WebHost.Endpoints.AppHostBase {
    // Register your Web service with ServiceStack.
public TicketServiceHost()
      : base("Ticket Service", typeof(TicketService).Assembly) {}
    public override void Configure(Funq.Container container) {
      // Register any dependencies your services use here.
}
  }
  protected void Application_Start(object sender, EventArgs e) {
    // Initialize your Web service on startup.
new TicketServiceHost().Init();
  }
}

Se a execução no IIS 7 e mais tarde, o item de configuração exibido em Figura 9 deve ser adicionado ao seu arquivo Web. config.

Figura 9 o arquivo Web. config para o IIS 7 e posterior

<configuration>
  <system.web>...</system.web>
  <!--Required for IIS 7 (and above) -->
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <handlers>
      <add path="*" name="ServiceStack.Factory"
        type="ServiceStack.WebHost.Endpoints.
ServiceStackHttpHandlerFactory, ServiceStack"
        verb="*" preCondition="integratedMode"
          resourceType="Unspecified"
        allowPathInfo="true" />
    </handlers>
  </system.webServer>
</configuration>

Quando você iniciar seu aplicativo da ServiceStack Web, seus contratos de serviço são listados como metadados de operações, como mostrado na Figura 10. Agora seu serviço da Web está pronto para aceitar as solicitações do cliente. Na próxima seção, fornecerei alguns exemplos de consumidor do serviço da Web de ServiceStack.


Figura 10 TicketService metadados

Built-in ServiceStack clientes

Grupo de desenvolvimento é muito franco contra o ServiceStack gerado código de cliente de serviço Web, então, o framework fornece um conjunto de built-in Web serviço clientes listados sob o serviço­Stack.ServiceClient.Web namespace. Todos os clientes internos implementam ServiceStack.Service.IServiceClient. Aqueles que suportam o resto implementam ServiceStack.Service.IRestClient.

Os clientes disponíveis incluem:

  • JsonServiceClient
  • JsvServiceClient
  • XmlServiceClient
  • MsgPackServiceClient
  • ProtoBufServiceClient
  • Soap11ServiceClient
  • Soap12ServiceClient

Cada um oferece suporte a um formato de serialização/desserialização diferentes. Seu uso é intercambiável porque eles implementam um conjunto de interfaces comuns.

Para manter as coisas simples, criar um aplicativo de console chamado ServiceStackClient para consumir o seu bilhete de ServiceStack­de serviço usando o JsvServiceClient. Se você quiser experimentar um cliente diferente, basta substitua o seguinte código JsvServiceClient com qualquer um dos clientes disponíveis listados anteriormente:

static void Main(string[] args) {
  Console.Title = "ServiceStack Console Client";
  using (var client = new JsvServiceClient("http://localhost:30542")) {
    List<Ticket> queuedTickets =
      client.Send<List<Ticket>>(new GetAllTicketsInQueueRequest());
    if (queuedTickets != null) {
      foreach (Ticket ticket in queuedTickets) {
        PrintTicket(ticket);
      }
    }
  }
}

O aplicativo de console faz o seguinte:

  • Consulta o TicketService para todos os bilhetes na fila.
  • Imprime os bilhetes resultantes que voltou do TicketService.

O console de saída é o exato mesmo assim gerada pelo cliente WCF, mostrado no Figura 3.

Mais para a oferta

Este artigo apenas arranhamos a superfície em que ServiceStack tem que oferecer aos usuários do WCF buscando soluções cross-platform. Nem sequer discuti suporte do ServiceStack para streaming, solicitações assíncronas e filas de mensagens, por exemplo.

Como você pode ver, algumas etapas adicionais são necessárias para compilar um serviço ServiceStack Web em oposição a um serviço Web WCF. No entanto, penso que o esforço é bastante insignificante para transformar a camada de serviço de um serviço Web do WCF Windows-ligado em um serviço de ServiceStack Web multiplataforma. Se eu tivesse ido em busca de independência de plataforma, uma rota diferente — por exemplo, usando um serviço da Web Java — o esforço e a curva de aprendizado seria muito maiores em comparação.

Apesar de tudo, se seu serviço da Web é destinado a executado somente em um sistema operacional Windows, então WCF é indiscutivelmente a melhor solução. Há menos sobrecarga quando estiver criando um serviço Web WCF do zero no ambiente Windows, e você não tem ainda um outro terceiros redistribuível para manter e implantar o sistema de destino.

Ngan Le  é um engenheiro de software sênior trabalhando estreitamente com o WCF, que recentemente começou a explorar o ServiceStack como uma solução multi-plataforma para serviços da Web.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Andrew Oakley (Microsoft)
Andrew Oakley é gerente sênior de programas sobre os padrões & equipe de práticas. Antes de se tornar um gerente de programa, Andrew passou dois anos como um evangelista técnico para o Visual Studio e a plataforma .NET. Seu projeto atual centra-se na orientação de acesso de dados em torno da construção de poliglota sistemas persistentes usando relacional e armazenamentos de dados NoSQL.