Sobes.tech
Junior

O que é RESTful e como é utilizado no desenvolvimento de web services?

sobes.tech IA

Resposta da IA

RESTful é um estilo arquitetónico para desenvolver sistemas distribuídos, como os serviços web. Baseia-se nos princípios do REST (Transferência de Estado Representacional).

Princípios principais do REST:

  • Cliente-servidor: separação clara entre Cliente e Servidor.
  • Sem estado (Stateless): o servidor não armazena informações sobre o estado do cliente entre pedidos. Cada pedido contém toda a informação necessária.
  • Cacheável: os clientes ou nós intermédios podem fazer cache das respostas.
  • Sistema em camadas: o sistema pode ser organizado em camadas, e cada camada vê apenas a mais próxima.
  • Código a pedido (opcional): o servidor pode expandir ou configurar temporariamente a funcionalidade do cliente transmitindo código executável.
  • Interface uniforme: princípio chave que inclui:
    • Identificação de recursos: os recursos são identificados por URI.
    • Manipulação de recursos através de representações: o cliente interage com o recurso através da sua representação (por exemplo, JSON, XML).
    • Mensagens auto-descritivas: cada mensagem contém informações suficientes para o seu processamento.
    • Hipermédia como motor de estado da aplicação (HATEOAS): as respostas do servidor contêm links para outros recursos, permitindo ao cliente descobrir ações e transições disponíveis de forma dinâmica.

No desenvolvimento de serviços web em C#, a arquitetura RESTful é frequentemente implementada usando ASP.NET Core Web API.

Exemplo típico de uso de RESTful em C#:

// Controlador para gerir o recurso "Produto"
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductRepository _productRepository;

    public ProductsController(IProductRepository productRepository)
    {
        _productRepository = productRepository;
    }

    // Obter todos os produtos (GET /api/products)
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Product>>> GetProducts()
    {
        var products = await _productRepository.GetAllAsync();
        return Ok(products);
    }

    // Obter produto por ID (GET /api/products/{id})
    [HttpGet("{id}")]
    public async Task<ActionResult<Product>> GetProduct(int id)
    {
        var product = await _productRepository.GetByIdAsync(id);

        if (product == null)
        {
            return NotFound();
        }

        return Ok(product);
    }

    // Criar novo produto (POST /api/products)
    [HttpPost]
    public async Task<ActionResult<Product>> CreateProduct(Product product)
    {
        await _productRepository.AddAsync(product);
        return CreatedAtAction(nameof(GetProduct), new { id = product.Id }, product);
    }

    // Atualizar produto existente (PUT /api/products/{id})
    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateProduct(int id, Product product)
    {
        if (id != product.Id)
        {
            return BadRequest();
        }

        var existingProduct = await _productRepository.GetByIdAsync(id);
        if (existingProduct == null)
        {
            return NotFound();
        }

        await _productRepository.UpdateAsync(product);
        return NoContent();
    }

    // Eliminar produto (DELETE /api/products/{id})
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteProduct(int id)
    {
        var product = await _productRepository.GetByIdAsync(id);
        if (product == null)
        {
            return NotFound();
        }

        await _productRepository.DeleteAsync(id);
        return NoContent();
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}

public interface IProductRepository
{
    Task<IEnumerable<Product>> GetAllAsync();
    Task<Product> GetByIdAsync(int id);
    Task AddAsync(Product product);
    Task UpdateAsync(Product product);
    Task DeleteAsync(int id);
}