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.

Curso de
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; }
    }
}
Curso de
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!

Curso de
CONHEÇA O CURSO
Deixe seu comentário

Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo.