crystal_api
Version, currently 0.3.21 version
- 0.3.2latestJan 10, 2016
github.com/akwiatkowski/crystal_api
Simple PostgreSQL REST API in Crystal with devise-like auth.
67 stars
0 dependents
License: LGPLv3
Installation
# Add this to your shard.yml
dependencies:
crystal_api:
github: akwiatkowski/crystal_api
version: ~> 0.3.2Then run:
shards installshard.yml
- Crystal
- no constraint declared
- License
- LGPLv3
- Author
- Aleksander Kwiatkowski <bobikx@poczta.fm>
Dependencies
Runtime Dependencies
- moonshine*github: dhruvrajvanshi/Moonshine
- crystal-pg*github: will/crystal-pg
README
# crystal_api
Toolset for creating REST Api in Crystal Language.
## Roadmap
- [x] Fix DB mapping to allow create database - add types of columns to definition list
- [x] Check and fix JSON mapping
- [x] Update action
- [x] Destroy action
- [x] Clean Postgres adapter
- [x] Rewrite for easier usage as lib
- [x] JSON response header
- [ ] Other DB engines (partially refactored)
- [ ] More predefined/sample controllers
- [ ] Websockets
- [ ] DB inline config (no confi file needed)
## Usage
1. Create empty crystal project:
`crystal init app crystal_api_sample`
2. Add `crystal_api` to `shard.yml`. Example:
```Yaml
name: crystal_api_sample
version: 0.1.0
authors:
- Crystal Guy <crystal@crystal.org>
dependencies:
crystal_api:
github: "akwiatkowski/crystal_api"
license: MIT
```
3. Update shards (Crystal libraries):
`shards update`
4. Create Postgresql connection file in `config/database.yml` using sample
from `config/database.yml.sample` from `crystal_api` repository.
```Yaml
host: localhost
database: crystal
user: crystal_user
password: crystal_password
```
5. Set path to Postgresql config file by adding in `src/crystal_api_sample.cr`
```Crystal
class CrystalApi::PgAdapter
def self.config_path
"config/database.yml"
end
end
```
6. Create model representing data fetched from Postgresql:
```Crystal
class EventModel < CrystalApi::CrystalModel
def initialize(_db_id, _name)
@db_id = _db_id as Int32
@name = _name as (String | Nil)
end
getter :db_id, :name
JSON.mapping({
"db_id": Int32,
"name": String,
})
DB_COLUMNS = {
# "id" is default
"name" => "varchar(255)",
}
DB_TABLE = "events"
end
```
Notes:
* nullable columns must use union with `Nil` class
* all columns should be defined in constructor
* JSON mapping is used when rendereing JSON
* DB_COLUMNS are used when creating table
* DB_TABLE is table name
7. Create service class which performs DB operations.
```Crystal
class EventsService < CrystalApi::CrystalService
def initialize(a)
@adapter = a
@table_name = EventModel::DB_TABLE
# create table if not exists
create_table(EventModel::DB_COLUMNS)
end
def self.from_row(rh)
return EventModel.new(rh["id"], rh["name"])
end
end
```
Notes:
* `EventsService.from_row(rh)` instantiates model from Hash-like
response from DB adapter
8. Create controller class with defined route paths.
```Crystal
class EventsController < CrystalApi::CrystalApi::Controllers::JsonRestApiController
def initialize(s)
@service = s
@router = {
"GET /events" => "index",
"GET /events/:id" => "show",
"POST /events" => "create",
"PUT /events/:id" => "update",
"DELETE /events/:id" => "delete",
}
@resource_name = "event"
end
end
```
Notes:
* `@resource_name` is used in `update` and `create`
* instead of `CrystalApi::CrystalController` please use
`CrystalApi::Controllers::JsonRestApiController`
9. Create app class
```Crystal
class ApiApp < CrystalApi::App
def initialize(a)
super(a)
@events_service = EventsService.new(@adapter)
@events_controller = EventsController.new(@events_service)
add_controller(@events_controller)
@port = 8002
end
end
```
Notes:
* `super` is important
* service and controller must be initialized here and controller must be added
* default port is 8000
* `initialize` utilize DB adapter class now
10. You can now run it
```Crystal
a = ApiApp.new( DbAdapter.new )
a.run
```
Notes:
* you must provide DB adapter instance for `ApiApp` constructor
## Index
GET http://localhost:8002/events
```
curl -H "Content-Type: application/json" -X GET http://localhost:8002/events
```
## Show
GET http://localhost:8002/events/:id
```
curl -H "Content-Type: application/json" -X GET http://localhost:8002/events/1
```
But first create an Event :)
## Create
POST http://localhost:8002/events
```
curl -H "Content-Type: application/json" -X POST -d '{"event":{"name": "test1"}}' http://localhost:8002/events
```
## Update
PUT http://localhost:8002/events/:id
```
curl -H "Content-Type: application/json" -X PUT -d '{"event":{"name": "test2"}}' http://localhost:8002/events/1
```
## Delete
DELETE http://localhost:8002/events/:id
```
curl -H "Content-Type: application/json" -X DELETE http://localhost:8002/events/1
```
## Contributing
1. Fork it ( https://github.com/akwiatkowski/crystal_api/fork )
2. Create your feature branch (git checkout -b my-new-feature)
3. Commit your changes (git commit -am 'Add some feature')
4. Push to the branch (git push origin my-new-feature)
5. Create a new Pull Request
## Contributors
- [akwiatkowski](https://github.com/akwiatkowski) Aleksander Kwiatkowski - creator, maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.3.2- Tagged
- Jan 10, 2016
- Commit
16efc57eb1eb- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/akwiatkowski/crystal_api
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 1