Web Services

Criando um Web Service com o ServiceStack – Parte 2

Dando continuidade ao estudo da biblioteca ServiceStack, neste artigo modificaremos o web service criado na primeira parte.

Os web services criados com essa biblioteca geralmente fazem uso dos outros recursos. Um deles é o ServiceStack.OrmLite, que é um micro framework ORM, que também já vimos anteriormente nesse artigo. Assim, vamos adicioná-lo na aplicação criada na primeira parte desse artigo.

C# (C Sharp) - Introdução ao ASP.NET Core
Curso de C# (C Sharp) - Introdução ao ASP.NET Core
CONHEÇA O CURSO

Colocando a mão na massa

Inicialmente iremos definir a classe responsável pela resposta do web service. Desta forma, dentro do projeto, na pasta ServiceModel, será criado a classe chamada TodoRespose, contendo o código abaixo:

using ServiceStack;

namespace ServiceStackExample.ServiceModel {
    public class TodoResponse
    {
        public object Result { get; set; }

        public ResponseStatus ResponseStatus { get; set; }
    }
}

A criação desta classe não é algo obrigatório, como o artigo anterior pode ter implicitado, mas gosto de separar a classe DTO do seu response.

Ainda dentro da pasta ServiceModel adicione a classe DTO Todo, conforme o código abaixo:

using ServiceStack;

namespace ServiceStackExample.ServiceModel {

    [Route("/todo")]
    [Route("/todo/{Id}")]
    public class Todo
    {
        public int Id { get; set; }
        public string Text { get; set; }
        public bool Done { get; set; }
    }
}
C# (C Sharp) Básico
Curso de C# (C Sharp) Básico
CONHEÇA O CURSO

Definindo o ServiceStack.OrmLite

Antes de criarmos um service para a classe DTO Todo, vamos configurar o acesso ao banco de dados.

A primeira coisa que deve ser feita é adicionar a referência da biblioteca no projeto:

dotnet add package ServiceStack.OrmLite.Sqlite.Core

Acima estou usando o pacote do banco de dados que irei utilizar neste artigo. Você pode ver as demais versões disponíveis aqui.

Não se esqueça de aplicar o restore no projeto:

dotnet restore

A classe POCO utilizada será a DTO Todo, assim já iremos definir o repositório dela.

Inicialmente criaremos uma classe abstrata, onde o acesso pelo OrmLite será definido:

using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
using ServiceStack.OrmLite;

namespace ServiceStackExample.Repositories
{
    public abstract class AbstractRepository<T>
    {
        private string _connectionString;
        private OrmLiteConnectionFactory _dbFactory;
        protected OrmLiteConnectionFactory DbFactory => _dbFactory;
        public AbstractRepository(IConfiguration configuration){
            _connectionString = configuration.GetValue<string>("DBInfo:ConnectionString");

            _dbFactory = new OrmLiteConnectionFactory(_connectionString, SqliteDialect.Provider);
        }
        public abstract void Add(T item);
        public abstract void Remove(int id);
        public abstract void Update(T item);
        public abstract T FindByID(int id);
        public abstract IEnumerable<T> FindAll();
    }
}

E a partir dele, será criado um repositório para a classe Todo:

using Microsoft.Extensions.Configuration;
using ServiceStackExample.ServiceModel;
using ServiceStack.OrmLite;
using System.Collections.Generic;

namespace ServiceStackExample.Repositories
{
    public class TodoRepository: AbstractRepository<Todo>
    {
        public TodoRepository(IConfiguration configuration): base(configuration) { }

        public override void Add(Todo item)
        {
            using (var db = DbFactory.Open())
            {
                if (db.CreateTableIfNotExists<Todo>())
                {
                    db.Insert(item);
                }
            }
        }
        public override void Remove(int id)
        {
            using (var db = DbFactory.Open())
            {
                db.Delete<Todo>(p => p.Id == id);
            }
        }
        public override void Update(Todo item)
        {
            using (var db = DbFactory.Open())
            {
                db.Update(item);
            }
        }
        public override Todo FindByID(int id)
        { 
            using (var db = DbFactory.Open())
            {
                return db.SingleById<Todo>(id);
            }
        }
        public override IEnumerable<Todo> FindAll()
        {
            using (var db = DbFactory.Open())
            { 
                if (db.CreateTableIfNotExists<Todo>())
                {
                    return db.Select<Todo>();
                }

                return db.Select<Todo>();
            }
        }
    }
}

Agora podemos definir o service.

Criando a classe Service

Agora na pasta ServiceInterface adicione uma classe chamada TodoService, contendo o código abaixo:

using Microsoft.Extensions.Configuration;
using ServiceStack;
using ServiceStackExample.Repositories;
using ServiceStackExample.ServiceModel;

namespace ServiceStackExample.ServiceInterface {
    public class TodoService: Service
    {
        private readonly TodoRepository todoRepository;

        public TodoService(IConfiguration configuration){
            todoRepository = new TodoRepository(configuration);
        }

        public object Get(Todo todo)
        {

            if(todo.Id != default(int))
                return todoRepository.FindByID(todo.Id);

            return todoRepository.FindAll();
        }

        public Todo Post(Todo todo){
            todoRepository.Add(todo);

            return todo;
        }

        public Todo Put(Todo todo){
            todoRepository.Update(todo);

            return todo;
        }

        public Todo Delete(Todo todo){
            todoRepository.Remove(todo.Id);

            return todo;
        }
    }
}

Diferente do artigo anterior, agora estamos definindo métodos para tratar todos os principais métodos do HTTP: GET, POST, PUT e DELETE.

Com isso definido, agora só é necessário criar a interface.

Interface gráfica

Como faltei em todas as aulas de front-end :P, nem vou explicar aqui os códigos deste detalhe, você pode baixar o projeto clicando aqui.

Após executar a aplicação, ela será exibida da seguinte forma:

Interface da aplicação

Com o código disponibilizado, você pode testá-la, para ver como ficou.

Um abraço!

C# (C Sharp) - ASP.NET MVC
Curso de C# (C Sharp) - ASP.NET MVC
CONHEÇA O CURSO

Segurança em SOA: Como proteger os web services?

No último artigo sobre SOA, vimos sobre a Arquitetura Orientada a Serviços e como ela funciona. Vimos que uma implementação dessa arquitetura pode ser realizada com qualquer tecnologia baseada em web, mas geralmente a SOA é implementada utilizando Web Services, já que estes são fáceis de implementar e distribuir. Estes mesmos web services também são responsáveis por expor, através de uma rede, um determinado serviço. Sendo assim, eles precisam de uma atenção especial quanto à segurança. Como saber se meus web services estão realmente protegidos?

HTTP - Fundamentos
Curso de HTTP - Fundamentos
CONHEÇA O CURSO

Serviços

Antes de qualquer coisa vamos retomar à definição sobre o que é um serviço. Para que se possa ter uma real governança em TI em uma empresa é necessário saber que isso não é atingido do dia para a noite. É um processo de longo prazo, por isso exige muita cautela dos processos como um todo, mantendo um alinhamento estratégico entre o negócio e a TI. O Negócio e a TI precisam trabalhar juntos!

Um dos autores mais famosos deste segmento, Thomas Erl, escreveu o livro SOA: Princípios do Design de Serviços, onde ele aborda 8 “regras” para definir um serviço. Nesse livro, ele enumera o que considera essencial para fazer uso da SOA “de verdade”. São eles:

Serviços são reutilizáveis

Essa é talvez uma das principais regras. Para isso acontecer, é necessária a interação da TI e do negócio. Quanto mais um serviço for genérico e puder ser reaproveitado, melhor!

Serviços compartilham um contrato formal

Todo serviço deve vir acompanhado de um “contrato”, onde ele deve informar o que o serviço faz e como ele se comunica.

Serviços possuem baixo acoplamento

Baixo acoplamento significa que certas implementações de um serviço podem ser modificadas, evoluídas e até mesmo substituídas, sem afetar negativamente os consumidores deste serviço.

Serviços abstraem a lógica

Serviços não devem expressar as regras de negócio. Os serviços SOA devem guardar os detalhes de sua implementação, até mesmo caso seja preciso modificar a lógica do negócio, não comprometendo as obrigações do serviço escritos no seu contrato.

Serviços são capazes de se compor de outros serviços

A composição também é uma forma de reutilização. Sendo assim, um serviço pode muito bem chamar um outro serviço para executar a sua tarefa.

Serviços são autônomos

Um serviço também deve ser autônomo, ou seja, apenas ele é suficiente para executar sua lógica.

Serviços evitam alocação de recursos por longos períodos

Quando um serviço é reutilizado, devemos tomar alguns cuidados. Não se deve criar muitas instâncias de um mesmo serviço, pois isso pode sobrecarregar a infra-estrutura. Para isso não acontecer, o serviço deve evitar reter informações específicas em uma determinada atividade.

Serviços devem possuir a capacidade de serem descobertos

O que eu quero dizer é que a capacidade dos serviços serem descobertos significa a visibilidade deles.

Para que isso ocorra, o contrato deve ser bem descrito, evitando que novos requerimentos resultem em serviços redundantes.

Agora que já entendemos um pouco melhor sobre como nossos serviços devem se comportar, vamos a um outro ponto do nosso artigo.

Imagine que uma empresa esteja fazendo o uso de SOA. O que pode acontecer se ela estiver utilizando um web service onde suas informações estão trafegando pela rede sem proteção???

Isso mesmo: acessos indevidos e possíveis interceptações das informações que trafegam pela infraestrutura dos serviços SOA!

Sendo assim, a necessidade de se proteger os recursos envolvidos com a aplicação da SOA no ambiente de TI é uma necessidade real.

Conheça o WS-Security: Segurança para Web Services

A tecnologia WS-Security (Web Services Security) é um padrão que tem a intenção de apoiar a SOA no sentido de prover segurança quando os dados são trocados. O WS-Security disponibiliza um sistema rico para prover segurança, tanto em confidencialidade quanto em autenticação.

Apesar disso, o WS-Security não funciona sozinho. Ele funciona em conjunto com as especificações WS-Policy e WS-SecurityPolicy. Essas especificações têm por objetivo, respectivamente, estabelecer políticas gerais a respeito de segurança, qualidade de serviço, confiabilidade; além de estabelecer quais são as políticas de segurança aplicáveis a um determinado serviço.

Na figura abaixo, podemos ver a estrutura de segurança que é fornecida pelo WS-Security, fazendo também uso da estrutura do WS-Policy.

Esses conceitos são baseados em cinco requisitos comuns de segurança: identificação, autenticação, autorização, confidencialidade e integridade.

Se um solicitante quiser acessar os serviços em segurança, primeiramente ele deve fornecer informações que expressem a sua origem. O WS-Security armazena essas informações em um cabeçalho padronizado, cujo ponto é referido como um token.

A autenticação requer a prova de que a mensagem que está sendo entregue ao destinatário é realmente do remetente que alega ser, fornecendo uma prova de que sua identidade reivindicada é verdadeira.

Após a autenticação, o destinatário pode precisar determinar se o solicitante está autorizado a fazer o que ele tenta fazer. Isto é chamado de autorização. Já a confidencialidade está diretamente ligada com a proteção e privacidade do conteúdo da mensagem, onde a mensagem deve ser mantida como confidencial e nenhum serviço ou mensagem não autorizada deve ver seu conteúdo.

Por último, temos a integridade, que garante que a mensagem não foi alterada desde a sua saída do remetente, garantindo que a mensagem permaneceu intacta a partir do momento de transmissão para o ponto de entrega.

Percebe a necessidade de se proteger as estruturas SOA em uma organização? Os benefícios adquiridos são muitos. Fazendo o uso correto das normas de segurança, a empresa poderá se beneficiar com o uso da SOA sem se preocupar com a integridade de suas informações, ponto de preocupação este que é de certa forma recorrente em organizações que iniciam o processo de adoção de uma arquitetura SOA.

Django - Templates
Curso de Django - Templates
CONHEÇA O CURSO

Você sabe o que é Arquitetura Orientada a Serviços (SOA)?

Quando estamos lidando com aplicações a nível empresarial, é muito comum ouvirmos sobre uns tais de Serviços SOA. É comum até mesmo ouvirmos os termos “barramento SOA” ou “fachada SOA”. E tudo isso dentro do que geralmente chamam de “arquitetura SOA”. Mas, o que é tudo isso? Será que estamos falando simplesmente de web services?

Afinal, o que realmente vem a ser SOA?

Uma solução fundamentada em SOA geralmente possui uma arquitetura baseada em padrões para a criação de uma infraestrutura de TI, visando simplificar as relações entre sistemas distintos, aperfeiçoando seu funcionamento e facilitando a incorporação de novos elementos. Sendo assim, caso haja mudanças nas necessidades do negócio, estes fatores permitem que a empresa responda a isso de forma rápida.

Essa exposição de regras de negócio é realizada basicamente através dos famosos web services, pois são eles que determinam os padrões e acabam especificando essa infraestrutura de TI que foi citada. A vantagem de termos essa estrutura em uma organização é justamente a flexibilidade que os web services trazem. Para isso ficar mais claro, vamos utilizar o seguinte exemplo:

Imagine que você tem uma infinidade de softwares que devem ser capazes de fazer a inserção de um novo cliente na base de dados de sua empresa. Cada um destes softwares é mantido por um prestador de serviços diferente e, pior ainda, cada um destes softwares foi escrito em uma linguagem diferente. Para piorar mais um pouquinho: sua organização tem uma série de validações que precisam ser realizadas antes de permitir a inserção desse novo cliente, sendo mandatório que todos os softwares realizem essas validações da maneira correta.

Para muitas empresas este é um cenário caótico. São sistemas que utilizam linguagens diferentes e desenvolvidos por pessoas diferentes fazendo a interação direta com o negócio da sua organização, além de existirem regras de validação a serem seguidas para garantir o sucesso e efetividade do negócio.

Desenvolvedor Java Júnior
Formação: Desenvolvedor Java Júnior
A formação Desenvolvedor Java nível Júnior da TreinaWeb tem como objetivo fornecer uma introdução ao desenvolvimento através do Java e todo o ecossistema para desenvolvimento da Oracle. Nesta formação, são abordados tópicos como o desenvolvimento da capacidade analítica, o paradigma orientado a objetos, a preparação do ambiente de desenvolvimento para o Java através do Eclipse e o controle de versão de código através do Git e do GitHub. Além disso, também são abordados aspectos mais essenciais da linguagem e estruturas importantíssimas dentro do ecossistema do Java, como a Stream API, que auxilia a lidar com coleções de dados; a implementação das estruturas de dados mais tradicionais como listas, filas e pilhas; e a API de coleções.
CONHEÇA A FORMAÇÃO

Sendo assim, como lidar com um cenário tão divergente?

Esse é exatamente o cenário perfeito para a utilização da arquitetura SOA, pois temos ativos de negócio envolvidos em um ambiente completamente heterogêneo. E todo mundo precisa conversar entre si.

Pensando em uma arquitetura voltada a serviços, nós poderíamos resolver isso de maneira muito fácil. Poderíamos criar um web service chamado “IncluirCliente”. Este web service será responsável por fazer todas as validações do cliente antes de o inserir na base de dados. Assim, caberia aos demais softwares simplesmente consumir esse serviço da maneira adequada.

Agora as coisas ficaram muito mais simples. Conseguimos centralizar o nosso ativo de negócio (no caso, o cliente e a sua inserção), garantindo que o fluxo de negócio dele sempre ocorra da maneira correta (temos certeza que o cliente sempre vai ser validado da maneira correta).

Também garantimos reutilização com esse web service: para qualquer software que necessite incluir clientes na base da organização, bastará a utilização deste web service. Sendo assim, facilitamos a relação entre os sistemas distintos da organização, pois qualquer linguagem é capaz de consumir um web service, o que coloca um pouco de ordem neste nosso ambiente completamente heterogêneo.

Por fim, garantimos extensibilidade pois, se quisermos um dia alterar a regra de negócio de validação do cliente ou mesmo acrescentar novas etapas do negócio, basta modificarmos o web service. Todos os softwares que consomem este web service serão automaticamente “atualizados”. Esta é a arquitetura SOA!

Mas então é só eu criar web services para que eu tenha uma arquitetura SOA?

Não, não basta criarmos e expormos web services para dizer que estamos utilizando uma arquitetura orientada a serviços. Perceba que temos um problema que vai muito além da questão técnica de criar ou não um web service em uma determinada linguagem. Temos a barreira do negócio. O modelo de negócio da organização fica exposto nos serviços quando estamos utilizando SOA. Por isso, é essencial uma completa integração entre o setor de negócios e o setor de tecnologia. Essa é outra intenção da utilização da arquitetura SOA: implementar tecnologia de ponta para o negócio da empresa, tornando-a mais competitiva no mercado.

Temos ainda várias outras questões envolvidas nesse processo: como fica a segurança dos dados trafegados, já que serviços SOA certamente receberão dados sensíveis para o negócio? Como saber o que pode ser exposto e o que não pode ser exposto? Como conseguir ter governança de TI de verdade em um ambiente orientado a serviços?

Nos próximos posts dessa série, iremos discutir mais sobre estes pontos. Até lá!