---
title: "Como Criar uma API REST com Golang e Gin - Parte 2: Estruturando os Handlers"
url: "https://golang.com.br/aprenda/api-rest-gin-parte2/"
markdown_url: "https://golang.com.br/aprenda/api-rest-gin-parte2.MD"
description: "Parte 2 da série: aprenda a estruturar handlers, criar rotas CRUD completas e gerenciar dados em memória com Golang e Gin."
date: "2026-04-30"
author: ""
---

# Como Criar uma API REST com Golang e Gin - Parte 2: Estruturando os Handlers

Parte 2 da série: aprenda a estruturar handlers, criar rotas CRUD completas e gerenciar dados em memória com Golang e Gin.


# Como Criar uma API REST com Golang e Gin - Parte 2: Estruturando os Handlers

Na Parte 1 criamos nosso primeiro endpoint. Agora vamos estruturar uma **API CRUD completa** para gerenciar uma biblioteca de livros.

## Modelo de Dados

Primeiro, defina a struct `Book` em `main.go` (ou em um arquivo `models/book.go`):

```go
type Book struct {
    ID     string  `json:"id"`
    Title  string  `json:"title"`
    Author string  `json:"author"`
    Price  float64 `json:"price"`
}
```

## Banco de Dados em Memória

Para simplificar, usaremos um slice em memória:

```go
var books = []Book{
    {ID: "1", Title: "Clean Code", Author: "Robert Martin", Price: 89.90},
    {ID: "2", Title: "The Go Programming Language", Author: "Alan Donovan", Price: 120.00},
}
```

## Handlers (Controllers)

Crie handlers separados para organizar o código:

```go
// GET /books - Lista todos os livros
func getBooks(c *gin.Context) {
    c.JSON(200, books)
}

// GET /books/:id - Busca um livro pelo ID
func getBook(c *gin.Context) {
    id := c.Param("id")
    for _, book := range books {
        if book.ID == id {
            c.JSON(200, book)
            return
        }
    }
    c.JSON(404, gin.H{"error": "Livro não encontrado"})
}

// POST /books - Cria um novo livro
func createBook(c *gin.Context) {
    var newBook Book
    if err := c.ShouldBindJSON(&newBook); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    books = append(books, newBook)
    c.JSON(201, newBook)
}

// PUT /books/:id - Atualiza um livro
func updateBook(c *gin.Context) {
    id := c.Param("id")
    var updatedBook Book
    if err := c.ShouldBindJSON(&updatedBook); err != nil {
        c.JSON(400, gin.H{"error": err.Error()})
        return
    }
    for i, book := range books {
        if book.ID == id {
            books[i] = updatedBook
            c.JSON(200, updatedBook)
            return
        }
    }
    c.JSON(404, gin.H{"error": "Livro não encontrado"})
}

// DELETE /books/:id - Remove um livro
func deleteBook(c *gin.Context) {
    id := c.Param("id")
    for i, book := range books {
        if book.ID == id {
            books = append(books[:i], books[i+1:]...)
            c.Status(204)
            return
        }
    }
    c.JSON(404, gin.H{"error": "Livro não encontrado"})
}
```

## Configurando as Rotas

```go
func main() {
    r := gin.Default()

    // Grupo de rotas para /books
    books := r.Group("/books")
    {
        books.GET("", getBooks)
        books.GET("/:id", getBook)
        books.POST("", createBook)
        books.PUT("/:id", updateBook)
        books.DELETE("/:id", deleteBook)
    }

    r.Run(":8080")
}
```

## Testando a API

Use `curl` ou Postman:

```bash
# Listar livros
curl http://localhost:8080/books

# Buscar livro
curl http://localhost:8080/books/1

# Criar livro
curl -X POST http://localhost:8080/books \
  -H "Content-Type: application/json" \
  -d '{"id":"3","title":"Domain-Driven Design","author":"Eric Evans","price":150.00}'

# Atualizar livro
curl -X PUT http://localhost:8080/books/1 \
  -H "Content-Type: application/json" \
  -d '{"id":"1","title":"Clean Code (Atualizado)","author":"Robert Martin","price":99.90}'

# Deletar livro
curl -X DELETE http://localhost:8080/books/3
```

## Próximos Passos

Na **Parte 3**, vamos:
- Adicionar validação de dados (binding + validator)
- Middleware para logging e autenticação
- Tratamento de erros estruturado

👉 [Parte 3: Validação e Middleware](/aprenda/api-rest-gin-parte3/)

---

*Gostou deste tutorial? Compartilhe no [Twitter](https://twitter.com/golangbr) e deixe seu feedback no [Telegram](https://t.me/golangbr)!*
