Microsoft KATANA Usando IIS

Microsoft KATANA Usando IIS

Olá pessoal, tudo bem? Recentemente escrevi um artigo que para muitos não é tão novidade, pois desde 2014 estamos vendo, ouvindo e lendo bastantes artigos sobre o assunto OWIN. O projeto Microsoft KATANA nasceu através de uma iniciativa do time AspNet da microsoft em implementar os padrões do OWIN e desenvolver um mecanismo de Web Server independente de Sistemas operacionais como é o caso do IIS e que estivesse aderente aos novos conceitos da web e aplicações web api.

O que significa KATANA?

Primeiramente gostaria de frisar que KATANA se trata, aqui, da histórica espada samurai super afiada e habilmente manuseada por poucos. Porém, assim como a espada KATANA consegue separar facilmente um tecido de ceda (por exemplo), o projeto Katana – desenvolvido pela Microsoft, separou a forma de pensar e desenvolver aplicativos para web. (Atualmente o Katana tornou-se vNext – mas como estamos fazendo uma retrospectiva dos processos, vamos focar no Katana por enquanto)

Katana foi completamente escrito do zero e totalmente baseado em cima dos padrões OWIN, fornecendo todas as camadas de pipeline que uma aplicação web pode ter, usando o IIS. Além de funcionar como um Host ou servidor, Katana disponibiliza de uma série de APIs para facilitar o desenvolvimento de aplicações que utilizam o OWIN, incluindo componentes como: Autenticação/Autorização (AspNet Identity), ferramentas de diagnósticos, servidor de arquivos estáticos, além de trabalhar facilmente com componentes de comunicação em tempo real, como é o caso do SignalR e integrar-se muito bem com Web APIs.

Os principios do KATANA

  • Portável [Portable]

Ser portável, imprime um comportamento dentro de aplicações utilizando Katana que diz que cada componente precisa ser substituível, desde o servidor web até a camada de aplicação. Atualmente, frameworks que são desenvolvidos por algumas grandes empresas ou até mesmo iniciativas open sources já são entregues para o mercado, levando-se em consideração os padrões OWIN. Os framworks devem rodar em cima de servidores e hosts de projetos baseados em OWIN.

  • Modular

Ser Modular para o projeto KATANA, quer dizer que todos os componentes fornecidos dentro desse tipo de projeto deve ser muito focado em simplicidade e, para aqueles que não conhecem essa expressão, YAGNI (You aren’t Gonna Need It ou Não faça nada além do necessário); Com isso, fornecer aos desenvolvedores a flexibilidade de mixar componentes a medida que for necessário ao funcionamento da aplicação. Isso manterá a aplicação com um tamanho pequeno, ao invés de grandes bibliotecas monolíticas, a exemplo: System.Web.dll.

  • *Leve e performático [Lightweight and Performant*]

Esse terceiro objetivo é alcançado devido as características do segundo objetivo: Ser uma plataforma Modular,**ou seja, a aplicação consumirá apenas e somente apenas o recurso que ela precisar. Além disso, uma vez os desenvolvidos os componentes para serem portáteis, estes podem ser substituidos por outras implementações mais performáticas, que as atuais.

Arquitetura

Antes de mergulharmos no desenvolvimento de aplicações utilizando KATANA, vamos entender um pouco da sua arquitetura e como as mensagens são tratadas entre as camadas definidas pelas especificações OWIN: HOST, Server, Middleware * e *Application, como mostra a figura abaixo:

clip_image001**

  1. Host

Esta camada é a primeira e a camada mais baixa que existe dentre todas as outras camadas especificadas pelos padrões OWIN. Essa camada é a responsável por realizar o trabalho "sujo": Inicializar a aplicação, finalizar todos os processos da aplicação, por exemplo. Além disso, tem um papel extremamente importante que é inicializar, gerenciar e orquestrar todo o pipeline do OWIN que serão utilizados para processar as entradas (Requests).

Para desenvolver uma aplicação utilizando dos novos recursos do projeto KATANA, estão listados abaixo três tipos de aplicação:

  • IIS/ASP.NET

O mais conhecido e mais fácil de todos e que, além disso, tem maior compatibilidade com aplicações legadas que usam o IIS – Neste cenário as aplicações utilizam o pipeline OWIN através dos padrões HttpModule e HttpHandler.

Através desta opção de Host, você será obrigado a utilizar o imenso e monolítico pacote web (o que muitos de nós não queremos mais, não é mesmo!?!?) o System.Web.

  • Custom Host (Self-Host)

Essa opção de host, é uma alternative para aqueles desenvolvedores que querem fugir insanamente do System.Web, gostam de ter todo o controle do processamento web e configurações em suas mãos (Sabem do que estão fazendo 😀). Isso permite que as aplicações possam ser hospedadas em uma Aplicação Console ou Windows Service, por exemplo.

  • OwinHost

Essa última opção destina-se queles desenvolvedores que não querem utilizar nada relacionado ao IIS/ASP.NET para hospedar suas aplicações web e também não querem cuidar de todo o trabalho “sujo” de ter que gerenciar o processamento das Requests/Reponses e querem trabalhar com algo pronto. Para esse cenário, a Microsoft desenvolveu uma ferramenta de linha de comando: OwinHost.exe. Essa ferramenta funciona através da pasta raís do projeto web e trabalha por meio do mecanismo HttpListener server, além de procurar e encontrar a classe Startup baseando-se em Code-By-Convention (Código através de convenção). Esse aplicativo tem algumas opções de linha de comando que podem ser utilizadas para configurar a forma como ele se comporta.

  1. Servidor [Server]

Essa camada também faz um outro trabalho "sujo" para o desenvolvedor que é abrir as conexões de socket, com a qual a aplicação responderá. A camada Server fica analisando se chegou alguma requisição (Request) e uma vez recebida uma dada requisição, um dicionário de dados é preenchido com as chaves e informações enviadas via requisição HTTP e envia esse dicionário para o pipeline do(s) Middleware(s) do OWIN, os quais foram configurados através da classe Startup.

  1. System.Web

Como mencionado anteriormente, a biblioteca monolítica System.Web e a opção de hospedagem IIS/ASP.NET não podem ser escolhidos independentemente um do outro. Ao usar esta opção, o servidor baseado no System.Web Katana se registra como HttpModule e HttpHandler e irá processar as solicitações enviadas a ele pelo IIS. Ele irá, em seguida, mapear o bem conhecido HttpRequest e objetos HttpResponse ao dicionário do Owin e enviar a solicitação para o pipeline do Owin.

  1. HttpListener

Esta é a opção que está disponível atualmente para trabalhar em conformidade com os padrões OWIN, seja utilizando OwinHost ou SelfHost.

  1. WebListener

Este é o servidor Owin super leve que está presente no ASP.NET vNext. Este tipo de servidor permite que aplicações ASP.NET possam ser utilizadas fora da aplicação do IIS. Ele funciona sob o kernel Http.Sys.

Para maiores informações acesse a documentação oficial.

  1. Midlleware

Após entendermos um pouco os primeiros pontos de entradas do request e quais são as camadas que as tratam, enfim chegamos de fato ao pipeline dos Middleware OWIN. Mas o que são os Middlewares? Middlewares são pequenos módulos de componentes de aplicações OWIN que implementam o delegate AppFunc.

Middlewares processam as requisições que chegam neles e após seu processamento ter sido concluido, é repassado para o próximo Middleware registrado no pipeline. O que cada um dos middlewares faz durante sua execução pode variar de um simples sistema de Logging até um sistema de validação extremamente complexo, a exemplo temos: SignalR, Web API, NancyFx.

  1. Application

Aqui está, de fato, o código de negócio da sua aplicação, sem mais nem menos Smile.

Criando um projeto KATANA usando IIS

Agora que já já sabemos um pouco quais são as inteções do OWIN, para o que ele se propõe e quais foram os objetivos da Microsoft ter investido tempo no projeto Katana. Vamos ao que interessa, Show me the Code Smile. Vamos abrir a IDE do Visual Studio 2015 e selecione o tipo de aplicação Web Application (.NET Framework 4.5.2) (nãoutilizem ainda a versão 4.6 vNext, pois não será o propósito deste artigo), conforme mostrado na imagem abaixo:
image

As opções listadas abaixo, precisam ser configuradas para que nossa aplicação de exemplo funcione:

image

Como você pode obersar na imagem acima, deixe as opções conforme mostrado na imagem. Como estamos criando um projeto Katana baseado em funcionalidades do IIS, teremos que conviver com o assembly monilitico chamado: System.Web, conforme apresentado na imagem abaixo:

image

*Incluindo os pacotes OWIN usando NuGet *

Com o projeto criado, precisamos adicionar as referências do Katana via NuGet.

Existem várias versões e tipos de pacotes que podem ser instalado via NuGet para aplicação que são construidas com base no Katana. Essa grande variedade de versões e pacotes ao mesmo tempo que facilita o desenvolvimento de aplicações web com base no Katana, por outro lado pode dificultar bastante no momento de saber escolher o pacote correto que sua aplicação precisa, o que pode tornar as coisas ainda mais complicadas para gerenciar e desenvolver. Apenas para deixar claro e frisar mais uma vez, nenhum pacote que você irá instalar daqui por diante, possui o nome "Katana" em seus respectivos nomes.

Vamos agora instalar o pacote do Owin Host *que faz uso do *System.Web. Vamos utilizar o Package Manager Console – vamos começar a usar algo menos visual Open-mouthed smile. Selecione a opção de menu Package Manager Console e digite a linha de comando abaixo:

PM> Install-Package Microsoft.Owin.Host.SystemWeb

O pacote instalado acima, depende diretamente de outros pacotes Owin Microsoft.Owin e Owin. Então, após a instalação do pacote acima, as dependências também devem ser instaladas no seu projeto.

image

Adicionando a classe Startup

Enfim chegamos ao começo do que todo desenvolvedor curte! Show ASAP (As Soon As Possible) the Code

Vamos adicionar a classe Startup ao projeto! É através dela que é feita orquestração e registro dos componentes que padronizam o comportamento que uma aplicação desenvolvida usando o Katana, deve ter para atender aos requisitos do padrão Owin. Em aplicações Katana existe um padrão para registrar a classe principal, o padrão é por conveção ou Code-By-Convention, ou seja, apenas nomeando a classe com o nome “Startup” e esta classe precisa estar localizada na raíz (root) da aplicação. O código que realiza a configuração do comportamento da aplicação, fica dentro do método Configuration.

Agora vamos adicionar a tal classe Startup! Clique com o botão direto no seu projeto, e selecione a opção "Add > New Item" e selecione a opção Startup Class – Essa opção está embaixo do menu do lado direito: Web > General, conforme apresentado na imagem abaixo:

image

Após a inclusão da classe no projeto, você vai observar que o template adicionou uma implementação assembly-level, para informar a engine do Katana que precisa inicializar primeiramente a classe Startup e executar o método Configration, pois será todo o comportamento das Requisições (Requests), Respostas (Reponses) e Pipeline serão orquestrados.

image

Como eu mencionei acima, tudo isso trabalha em cima de convenção por código (Code-By-Convention), o que não se faz necessário ter esse atributo assembly em seu código da classe Startup. Mas lembre-se, caso você tenha uma classe com nome diferente do padrão, esse atributo será completamente essencial para a inicialização da sua aplicação. Para provar que para uma aplicação padrão esse atributo não é necessário, basta comentar essa linha, colocar um breakpoint dentro do método Configuration e executar a sua aplicação Smile. Sua aplicação deve parar no Breakpoint como mostra a imagema abaixo:

image

Mas onde está o código? Bom, a melhor parte deixamos para o final (o que na verdade é apenas o começo da série Open-mouthed smile). Vamos colocar um pouco de alegria e emoção nesse artigo: Let’s go to code!!!

Para imprimir alguma coisa na tela podemos colocar um formulário simples, porém utilizando mecanismos do pipeline do Katana para renderizar o HTML. Abaixo você vai encontrar o código, que pode ser adicionado ao método Configuration:

public void Configuration(IAppBuilder app)  
{
    var htmlFilePath = System.Web.HttpContext.Current.Server.MapPath("~/html/formulario.html");
    var html = File.ReadAllText(htmlFilePath);
    app.Run(context => { context.Response.ContentType = "text/html";
        return context.Response.WriteAsync(html);
    });
}

Para que o código acima funcione, adicionei uma pasta na raíz do projeto, chamada: "html" e dentro dela acionei um arquivo .html com o nome “formulário.html” e dentro desse artigo inseri um código html contendo um formulário html simples.

O código acima, aprenseta 2 helpers do Owin – Lembrando: Estes helpers são todos baseados nas especificações do Owin:

  • IOwinContext – Interface responsável por conter informações do dicionário do Owin. As informações dessas chaves, você pode encontrar no primeiro artigo da série aqui.
  • Run – Este método trabalha com conceitos assíncronos. É um método de extensão com o propósito de adicionar o código a ser executado no final do pipeline do Owin. Segue a assinatura deste método de extensão: Run(System.Func *handler)*.

Agora, que tal implementarmos o mesmo código acima, usando uma forma de implementação na unha? Já pensou como famos implementar né? Open-mouthed smile

public void Configuration(IAppBuilder app)  
{
    app.Use(new Func<AppFunc, AppFunc>(next => (env => {var response = env["owin.ResponseBody"] as Stream;
    var headers = env["owin.ResponseHeaders"] as IDictionary<string, string[]>; 
    headers["Content-Type"] = new[] { "text/html" };
    var htmlFilePath = System.Web.HttpContext.Current.Server.MapPath("~/html/formulario.html");
    var html = File.ReadAllText(htmlFilePath);
    return response.WriteAsync(Encoding.UTF8.GetBytes(html), 0, html.Length); })));
}

Analisando o código acima, você vai observar que não estamos mais utilizando os Helpers do Katana. Sendo assim, somos obrigado a utilizar o método .Use para inserir o trecho de código que será executado dentro do pipeline do Owin. O exemplo acima, não fez uso do parâmetro next, que contém o elemento a seguir no pipeline. Além disso, você tem que pegar as chaves de resposta que são fornecidas pelo Owin, através de um dicionário de ambiente.

Conclusão

Hoje tentei passar um pouco sobre o que é Katana e quando utilizar. Fiz questão de realizar uma introdução com alguns detalhe sobre como funciona o pipeline do Owin/Katana e mostrar a importância de se ter esses conceitos e entendimento do seu fluxo e funcionamento. Além do pipeline, apresentei algumas das possibilidades que você pode escolher como Host de sua aplicação (de preferência escolham, quando puder: OwinHostouSelf-HostSmile). Começamos, finalmente ao que interessa aos desenvolvedores: Código! Mas lembre-se que uma boa teoria e quando bem fundamentada, faz toda diferença no dia-a-dia de nós desenvolvedores. Com isso, aprendemos um pouco como utilizar Helpers do Katana e que implementam os padrões Owin e como podemos implementar um trecho de código que possa ser executado dentro do Pipeline do Owin.

Espero que esse artigo seja útil para você. Um grande abraço e até o próximo artigo da série: Microsoft KATANA.

O código do exemplo acima, encontra-se no meu repositório no GitHub.

Comments