- Go 100%
| .zed | ||
| internal | ||
| testdata | ||
| .gitignore | ||
| api.http | ||
| go.mod | ||
| go.sum | ||
| main.go | ||
| README.md | ||
go-api-crud
API REST de libros (CRUD) escrita en Go con SQLite, organizada en capas.
│ main.go
└───internal
├───model
│ libro.go
├───service
│ book_service.go
├───store
│ book_store.go
└───transport
book_handler.go
¿Por qué esta estructura?
- model/: Define nuestras estructuras de datos
- store/: Maneja la base de datos (Repository Pattern)
- service/: Contiene la lógica de negocio
- transport/: Maneja HTTP request/responses
Cómo ejecutarlo
go run .
El servidor escucha en http://localhost:8080. La base de datos es SQLite y se crea sola
en ./books.db (está en .gitignore). Para empezar de cero, basta con borrar ese fichero.
Endpoints
| Método | Ruta | Descripción |
|---|---|---|
| GET | /books |
Lista todos los libros |
| POST | /books |
Crea un libro |
| GET | /books/{id} |
Obtiene un libro por id |
| PUT | /books/{id} |
Actualiza un libro |
| DELETE | /books/{id} |
Elimina un libro |
El cuerpo JSON usa los campos title y author. title no puede estar vacío.
Pruebas con curl
🧩 ¿Usas la extensión REST Client de VS Code? Tienes todas estas llamadas listas para enviar en el fichero
api.http.
💡 Estos comandos son idénticos en Windows (PowerShell) y en Linux/macOS. Para no pelearse con las comillas de cada shell, el cuerpo JSON se envía desde un fichero (
-d @fichero.json), usando los ejemplos de la carpetatestdata/. El-w "\n[status=%{http_code}]\n"solo sirve para ver el código de estado; puedes quitarlo.
1. Listar todos los libros (base vacía)
curl -s -w "\n[status=%{http_code}]\n" http://localhost:8080/books
[]
[status=200]
2. Crear un libro
curl -s -w "\n[status=%{http_code}]\n" -X POST http://localhost:8080/books -H "Content-Type: application/json" -d @testdata/libro.json
{"id":1,"title":"Cien años de soledad","author":"Gabriel García Márquez"}
[status=201]
3. Listar de nuevo (ya con datos)
curl -s -w "\n[status=%{http_code}]\n" http://localhost:8080/books
[{"id":1,"title":"Cien años de soledad","author":"Gabriel García Márquez"}]
[status=200]
4. Obtener un libro por id
curl -s -w "\n[status=%{http_code}]\n" http://localhost:8080/books/1
{"id":1,"title":"Cien años de soledad","author":"Gabriel García Márquez"}
[status=200]
5. Obtener un libro que no existe
curl -s -w "\n[status=%{http_code}]\n" http://localhost:8080/books/999
No lo encontramos
[status=404]
6. Id no numérico
curl -s -w "\n[status=%{http_code}]\n" http://localhost:8080/books/abc
No lo encontré
[status=400]
7. Crear sin título (validación)
curl -s -w "\n[status=%{http_code}]\n" -X POST http://localhost:8080/books -H "Content-Type: application/json" -d @testdata/libro_sin_titulo.json
Título vacío
[status=400]
8. Cuerpo null
curl -s -w "\n[status=%{http_code}]\n" -X POST http://localhost:8080/books -H "Content-Type: application/json" -d @testdata/libro_null.json
input inválido
[status=400]
9. JSON mal formado
curl -s -w "\n[status=%{http_code}]\n" -X POST http://localhost:8080/books -H "Content-Type: application/json" -d @testdata/libro_malformado.json
unexpected EOF
[status=400]
10. Actualizar un libro
curl -s -w "\n[status=%{http_code}]\n" -X PUT http://localhost:8080/books/1 -H "Content-Type: application/json" -d @testdata/libro_update.json
{"id":1,"title":"Cien años de soledad (edición revisada)","author":"Gabriel García Márquez"}
[status=200]
11. Actualizar sin título (validación)
curl -s -w "\n[status=%{http_code}]\n" -X PUT http://localhost:8080/books/1 -H "Content-Type: application/json" -d @testdata/libro_sin_titulo.json
Título vacío
[status=400]
12. Actualizar un id que no existe
curl -s -w "\n[status=%{http_code}]\n" -X PUT http://localhost:8080/books/999 -H "Content-Type: application/json" -d @testdata/libro_update.json
No lo encontramos
[status=404]
13. Método no permitido
curl -s -w "\n[status=%{http_code}]\n" -X PATCH http://localhost:8080/books
curl -s -w "\n[status=%{http_code}]\n" -X PATCH http://localhost:8080/books/1
Método no disponible
[status=405]
14. Eliminar un libro
curl -s -w "\n[status=%{http_code}]\n" -X DELETE http://localhost:8080/books/1
[status=204]
15. Eliminar un libro que ya no existe
curl -s -w "\n[status=%{http_code}]\n" -X DELETE http://localhost:8080/books/1
No lo encontramos
[status=404]
Notas sobre las comillas según el shell
Con los ficheros de testdata/ no hay problema, pero si prefieres el cuerpo en línea:
- bash / Linux / macOS / Git Bash: comillas simples normales:
curl -X POST http://localhost:8080/books -H "Content-Type: application/json" -d '{"title":"Un libro","author":"Autor"}' - Windows PowerShell: hay que escapar las comillas interiores con
\, y solo funciona si el JSON no tiene espacios:curl.exe -X POST http://localhost:8080/books -H "Content-Type: application/json" -d '{\"title\":\"UnLibro\",\"author\":\"Autor\"}'
Por eso se recomienda usar -d @fichero.json, que es idéntico en los dos shells.
Códigos de estado usados
| Código | Cuándo |
|---|---|
| 200 | GET correcto / PUT correcto |
| 201 | Libro creado |
| 204 | Libro eliminado (sin cuerpo) |
| 400 | Id inválido, JSON inválido o título vacío |
| 404 | Libro no encontrado (GET/PUT/DELETE sobre un id inexistente) |
| 405 | Método HTTP no soportado |
| 500 | Error interno (p. ej. fallo de base de datos) |