https://github.com/yuri-karpovich/api_hanami
JSON API based on Hanami::API
https://github.com/yuri-karpovich/api_hanami
hanami json-api
Last synced: about 1 year ago
JSON representation
JSON API based on Hanami::API
- Host: GitHub
- URL: https://github.com/yuri-karpovich/api_hanami
- Owner: yuri-karpovich
- Created: 2020-10-12T15:33:58.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2021-09-28T13:05:20.000Z (over 4 years ago)
- Last Synced: 2023-09-06T22:09:14.645Z (over 2 years ago)
- Topics: hanami, json-api
- Language: Ruby
- Homepage:
- Size: 22.5 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# API app example
## Objectives
This is am example app. My goal was to create a concurrent? small and fast JSON API app. Requirements:
- API calls should be faster than 100ms after data seeding (see [Data Seed](#data-seed))
- DB = PostgreSQL
- It's allowed to use any gems and ORMs
- Don't use RoR
- It's allowed to use DB capabilities to speed up responses
- Code should be clean, e.g. don't use generators
- Specs are required
### Endpoints
There are 3 models - `User` (fields: login), `Post` (fields: title, content, author ip address) and `Rating` (fields: value(1..5)). `Rating` belongs to `Post`, `Post` belongs to `User`.
#### Create Post
Params: title, content, author ip, author login
Behaviour: Create post. Create user if not exists
Response: 200 - created post attributes, 422 - in case of error
> `POST http://127.0.0.1:9292/api/v1/posts?login=&title=&ip=&content=`
#### Rate Post
Params: post id, rating
Behaviour: post has many ratings
> Important: action should work correctly on a concurrent update of the same post
Response: 200 - average post rating, 422 - in case of error
> `PUT http://localhost:9292/api/v1/posts/?rating=`
#### Top Posts by Rating
Params: number of posts to return (optional)
Behaviour: Collection of posts with their attributes should be returned
Response: 200 - N posts with their attributes
> `GET http://localhost:9292/api/v1/posts?count=`
#### List of IP addresses
Params: user logins
Behaviour: Get all user's IP addresses from his posts. It should be possible to get some users simultaneously
Response: 200 - users and their IP addresses
> `GET http://localhost:9292/api/v1/users/ip?logins=%20`
### Data Seed
`db/seed.db` file should be created. Import data to the DB using JSON API - start server and use API endpoints.
DB should be filled with:
- 100 uniq users
- 50 uniq IP addresses
- 200k posts
## Solution
This was my first non-Rails API app so I decided to create an app from scratch using something extremely light and fast.
I should have used `Roda` or `Hanami` but my decision was to try something experimental :)
So my choice for this test task is [`Hanami::API`](https://github.com/hanami/api).
> Actually I've benchmarked requests/second for `Hanami::API`, `Hanami::Router` and `Roda` on ruby 2.7.0 and the winner was `Hanami::Router`. `Roda` was very close to it.
> Anyway I would prefer `Hanami` or `Roda` for production.
## Quick start
Install gems:
bundle install
Start Postgres server:
docker-compose up -d
Prepare database:
bundle exec rake db:create RACK_ENV=production
bundle exec rake db:migrate RACK_ENV=production
Start server:
bundle exec bin/rackup -q -E production -o 127.0.0.1
Start data seed:
bundle exec rake db:seed RACK_ENV=production
## Run tests
bundle exec rake db:create RACK_ENV=test
bundle exec rake db:migrate RACK_ENV=test
bundle exec rspec