En este post vamos a crear una API REST usando el lenguaje Crystal, el microframework Kemal, y la base de datos SQLite, sin depender de ORMs.
El objetivo: lograr una API rápida, compilada a binario, y con sintaxis clara.
Asegurate de tener instalado:
- Crystal
- Shards (el gestor de dependencias)
- SQLite3
Verificá con:
crystal --version
sqlite3 --version
Creamos el proyecto base:
crystal init app kemal_api
cd kemal_api
Editá el archivo shard.yml y agregá las dependencias:
dependencies:
kemal:
github: kemalcr/kemal
sqlite3:
github: crystal-lang/crystal-sqlite3
Instalá las dependencias:
shards install
Creamos una base de datos SQLite y una tabla simple:
sqlite3 data.db "CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, email TEXT);"
A hacer las apis:
require "kemal"
require "sqlite3"
require "json"
DB_URL = "sqlite3://./data.db"
# --- Funciones de acceso a la base de datos ---
def get_users
users = [] of Hash(String, String)
DB.open DB_URL do |db|
db.query("SELECT id, name, email FROM users") do |rs|
rs.each do
users << {
"id" => rs.read(Int32).to_s,
"name" => rs.read(String),
"email" => rs.read(String)
}
end
end
end
users
end
def get_user(id : Int32)
DB.open DB_URL do |db|
db.query_one?("SELECT id, name, email FROM users WHERE id = ?", id, as: {Int32, String, String})
end
end
def create_user(name : String, email : String)
DB.open DB_URL do |db|
db.exec("INSERT INTO users (name, email) VALUES (?, ?)", name, email)
end
end
# --- Rutas Kemal ---
get "/users" do
get_users.to_json
end
get "/users/:id" do |env|
id = env.params.url["id"].to_i
if user = get_user(id)
{ id: user[0], name: user[1], email: user[2] }.to_json
else
env.response.status_code = 404
{ error: "User not found" }.to_json
end
end
post "/users" do |env|
data = JSON.parse(env.request.body.not_nil!)
create_user(data["name"].as_s, data["email"].as_s)
env.response.status_code = 201
{ message: "User created" }.to_json
end
Kemal.run
Ejecutá:
crystal run src/kemal_api.cr
La API se levanta en http://localhost:3000
Con Get
curl http://localhost:3000/users
Con Post
curl -X POST http://localhost:3000/users \
-H "Content-Type: application/json" \
-d '{"name": "Emanuel", "email": "ema@example.com"}'
Buscar un nuevo users es con id:
curl http://localhost:3000/users/1
Con Crystal + Kemal + SQLite podés construir APIs REST livianas, rápidas y auto-contenidas, ideales para proyectos pequeños o microservicios.
El código es legible, la ejecución veloz, y la experiencia de desarrollo tan fluida como en Ruby, pero con el rendimiento de C.
.png)