Receber por email
← Voltar para o catálogo

dotnet-legacy-api-controllers

Generates RESTful API Controllers with proper routing, versioning, authorization, and MediatR integration. Follows REST conventions and Clean Architecture patterns.

66estrelas
Atualizado há 5 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add ronnythedev/dotnet-clean-architecture-skills

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/dotnet-legacy-api-controllers/svg)](https://www.skillteca.com.br/skills/dotnet-legacy-api-controllers)

Skills relacionadas

Ver todas de Automação →

Alerta por categoria

Receba novas skills de Automação toda segunda

1 email curto, só com as skills novas de Automação. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

API Controller Generator

Overview

This skill generates RESTful API Controllers following best practices:

  • MediatR integration - Send commands/queries via ISender
  • API versioning - URL segment versioning
  • Authorization - Role and permission-based
  • Consistent responses - Proper HTTP status codes
  • Request/Response DTOs - Separate from domain

Quick Reference

| HTTP Method | Action | Returns | |-------------|--------|---------| | GET /{id} | Get by ID | 200 OK / 404 Not Found | | GET / | Get all/list | 200 OK | | POST / | Create | 201 Created / 400 Bad Request | | PUT /{id} | Full update | 200 OK / 404 Not Found | | PATCH /{id} | Partial update | 200 OK / 404 Not Found | | DELETE /{id} | Delete | 204 No Content / 404 Not Found |

Controller Structure

/API/Controllers/
├── {Feature}/
│   ├── {Entity}Controller.cs
│   ├── Request{Action}{Entity}.cs
│   └── ...
└── ...

Template: Complete CRUD Controller

// src/{name}.api/Controllers/{Feature}/{Entity}Controller.cs
using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using {name}.application.{feature}.Create{Entity};
using {name}.application.{feature}.Delete{Entity};
using {name}.application.{feature}.Get{Entity}ById;
using {name}.application.{feature}.Get{Entities};
using {name}.application.{feature}.Update{Entity};
using {name}.infrastructure.authorization;

namespace {name}.api.Controllers.{Feature};

[Authorize]
[ApiController]
[ApiVersion(ApiVersions.V1)]
[Route("api/v{version:apiVersion}/{entities}")]
public class {Entity}Controller : ControllerBase
{
    private readonly ISender _sender;

    public {Entity}Controller(ISender sender)
    {
        _sender = sender;
    }

    // ═══════════════════════════════════════════════════════════════
    // GET: api/v1/{entities}/{id}
    // ═══════════════════════════════════════════════════════════════
    [HttpGet("{id:guid}")]
    [ProducesResponseType(typeof({Entity}Response), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> GetById(
        Guid id,
        CancellationToken cancellationToken)
    {
        var query = new Get{Entity}ByIdQuery(id);

        var result = await _sender.Send(query, cancellationToken);

        if (result.IsFailure)
        {
            return NotFound(result.Error);
        }

        return Ok(result.Value);
    }

    // ═══════════════════════════════════════════════════════════════
    // GET: api/v1/{entities}
    // ═══════════════════════════════════════════════════════════════
    [HttpGet]
    [ProducesResponseType(typeof(IReadOnlyList<{Entity}ListResponse>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetAll(CancellationToken cancellationToken)
    {
        var query = new GetAll{Entities}Query();

        var result = await _sender.Send(query, cancellationToken);

        return Ok(result.Value);
    }

    // ═══════════════════════════════════════════════════════════════
    // GET: api/v1/{entities}/organization/{organizationId}
    // ═══════════════════════════════════════════════════════════════
    [HttpGet("organization/{organizationId:guid}")]
    [HasPermission(Permissions.{Entities}Read)]
    [ProducesResponseType(typeof(IReadOnlyList<{Entity}Response>), StatusCodes.Status200OK)]
    public async Task<IActionResult> GetByOrganizationId(
        Guid organizationId,
        CancellationToken cancellationToken)
    {
        var query = new Get{Entities}ByOrganizationIdQuery(organizationId);

        var result = await _sender.Send(query, cancellationToken);

        return Ok(result.Value);
    }

    // ═══════════════════════════════════════════════════════════════
    // POST: api/v1/{entities}
    // ═══════════════════════════════════════════════════════════════
    [HttpPost]
    [HasPermission(Permissions.{Entities}Write)]
    [ProducesResponseType(typeof(Guid), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> Create(
        [FromBody] RequestCreate{Entity} request,
        CancellationToken cancellationToken)
    {
        var command = new Create{Entity}Command(
            request.Name,
            request.Description,
            request.OrganizationId);

        var result = await _sender.Send(command, cancellationToken);

        if (result.IsFailure)
        {
            return BadRequest(result.Error);
        }

        return CreatedAtAction(
            nameof(GetById),
            new { id = result.Value },
            result.Value);
    }

    // ═══════════════════════════════════════════════════════════════
    // PUT: api/v1/{entities}/{id}
    // ═══════════════════════════════════════════════════════════════
    [HttpPut("{id:guid}")]
    [HasPermission(Permissions.{Entities}Write)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Update(
        Guid id,
        [FromBody] RequestUpdate{Entity} request,
        CancellationToken cancellationToken)
    {
        var command = new Update{Entity}Command(
            id,
            request.Name,
            request.Description);

        var result = await _sender.Send(command, cancellationToken);

        if (result.IsFailure)
        {
            return result.Error.Code.Contains("NotFound")
                ? NotFound(result.Error)
                : BadRequest(result.Error);
        }

        return Ok();
    }

    // ═══════════════════════════════════════════════════════════════
    // PATCH: api/v1/{entities}/{id}
    // ═══════════════════════════════════════════════════════════════
    [HttpPatch("{id:guid}")]
    [HasPermission(Permissions.{Entities}Write)]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> PartialUpdate(
        Guid id,
        [FromBody] RequestPatch{Entity} request,
        CancellationToken cancellationToken)
    {
        var command = new Patch{Entity}Command(id, request);

        var result = await _sender.Send(command, cancellationToken);

        if (result.IsFailure)
        {
            return result.Error.Code.Contains("NotFound")
                ? NotFound(result.Error)
                : BadRequest(result.Error);
        }

        return Ok();
    }

    // ═══════════════════════════════════════════════════════════════
    // DELETE: api/v1/{entities}/{id}
    // ═══════════════════════════════════════════════════════════════
    [HttpDelete("{id:guid}")]
    [HasPermission(Permissions.{Entities}Write)]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<IActionResult> Delete(
        Guid id,
        CancellationToken cancellationToken)
    {
        var command = new Delete{Entity}Command(id);

        var result = await _sender.Send(command, cancellationToken);

        if (result.IsFailure)
        {
            return result.Error.Code.Contains("NotFound")
                ? NotFound(result.Error)
                : BadRequest(result.Error);
        }

        return NoContent();
    }
}

Template: Request DTOs

// src/{name}.api/Controllers/{Feature}/RequestCreate{Entity}.cs
namespace {name}.api.Controllers.{Feature};

public sealed class RequestCreate{Entity}
{
    public required string Name { get; init; }
    public string? Description { get; init; }
    public Guid OrganizationId { get; init; }
}

// src/{name}.api/Controllers/{Feature}/RequestUpdate{Entity}.cs
public 
Compartilhar X LinkedIn