Boilerplate for a RESTful JSON rails-api using Postgres. The goal is to create a template for most APIs such that only the domain specific models & logic need to be added. It also acts as a minimum deployable system if you use AWS.
- Rspec preconfigured w/ FactoryGirl.
- Rspec integration tests for User Registration, Confirmation, Login, & Logout.
- API Versioning via requests, aka, 'api/v1/...' & ability to specify version in request headers if enabled.
- Added functionality such that logging out invalidates an auth token.
- Provided Dockerfile for easy developer setup and deployment.
- Provided scripts, configuration files, and instructions for deployment to AWS ElasticBeanstalk
Made from the following tutorials: https://github.com/thoulike/rails-api-authentication-token-example,http://apionrails.icalialabs.com/book/chapter_two. Thanks!
Users are required to register and confirm their email address. Once registered, upon login they receive a token that can be sent in the headers of future requests for authorization. Once issued, the token does not change. A new token is generated on sign out and can be obtained by signing in again. See spec/requests/users_spec.rb
for details.
Use your favorite HTTP Client to generate the following requests:
POST /api/v1/users HTTP/1.1
Host: 192.168.99.100:8080
Content-Type: application/json
Cache-Control: no-cache
{ "user" : { "email" : "[email protected]", "password" : "mybadpassword" }}
Depending on how you have configured email deliveries, you should get an email with a confirmation link. By default, the email is printed in the server logs.
The link should look like the following:
http://192.168.99.100:8080/api/v1/users/confirmation?confirmation_token=ZxvbZx3smFTFnFjm8AYA
POST /api/v1/users/sign_in HTTP/1.1
Host: 192.168.99.100:8080
Content-Type: application/json
Cache-Control: no-cache
{ "user" : { "email" : "[email protected]", "password" : "mybadpassword" }}
This will return an authentication_token
which you will set as the X-User-Token
header in future requests.
GET /api/v1/example HTTP/1.1
Host: 192.168.99.100:8080
Content-Type: application/json
X-User-Token: fXue2vifDPbxJ1v-n3c1
X-User-Email: [email protected]
Cache-Control: no-cache
- Update
APP_NAME
inconfig/application.rb
to your project name. Don't forget to change the module name too. - Execute
init_rvm.rb <PROJECT_NAME>
to create rvm files - Update
config/database.yml
with desired settings. (Defaulted to Docker Compose configuration)
- These instructions haven't been tests, please provide corrections!
- For Mac & Windows install Docker Toolbox https://www.docker.com/toolbox (or Boot2docker http://boot2docker.io/)
- If not installed with Docker Toolbox or Boot2docker, install Docker https://docs.docker.com/installation/
- If not installed with Docker Toolbox, then install Docker Compose https://docs.docker.com/compose/install/
- Execute
docker-compose run web rake db:migrate
- Execute
docker-compose build
- Execute
docker-compose up
- If using Docker Toolbox, use
docker-machine ip default
to get the IP. If using Boot2docker, executeboot2docker ip
to get the IP to use when making requests to the Rails server. - Test the Rails server is running with
curl <INSERT IP>:8080/api/v1/example
. You should get{"error":"You need to sign in or sign up before continuing."}
as a response.
The project directory should already be mounted inside the container, so you should be able to make live changes. However, since the project is running in the 'web' container, you need to prepend commands with docker-compose run web
.
You'll likely want to add the following aliases:
alias dm='docker-machine'
alias dc='docker-compose'
alias dcrw='docker-compose run web'
That way your commands can be shortened to:
dcrw rake routes
dcrw rspec
If there's a better way, I'm all ears.
- Install postgres (see instructions below)
- Create users and databases using
./init_pg_db.rb
(it uses database.yml) - Run
bundle exec rake db:create db:migrate
- Run
bundle exec rails s
- Test with
curl localhost:3000/api/v1/example
. You should get a 'You need to sign in' response.
- Install homebrew
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
brew install postgres
- First time db initialization
initdb /usr/local/var/postgres -E utf8
- Start Postgres
pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start
- Start an account with https://codeship.com, create a project and link it to your github/bitbucket account.
- Add
./scripts/setup_test.sh
as a test setup command. - Add
bundle exec rspec
as the test pipeline command. - Push to your configured branch to run CI tests!
- Create a new AWS Access Key. See documentation. NOTE: You'll need these credentials later to configure Codeship.
- Create a 'User Policy' for the User created in the previous step. Creating a custom inline policy is likely the easiest. Set the policy to the following. NOTE: These permissions will work but are too permissive and should be narrowed to only apply to the necessary resources ASAP. PRs welcome to improve the example policy.
- Create a new AWS Elastic Beanstalk application: select a name, select 'Create web server', select Generic 'Docker' platform, select 'single instance', select 'Sample Application', make up a environment name, select 'create RDS DB Instance'.
- Make an EC2 key pair if you haven't already. See documentation. Refresh key pair list if necessary and select your key pair. Leave other options as default.
- Skip making Environment tags.
- Select postgres as DB engine for RDS Configuration, create secure username and password for you database. Leave other options as default.
- Select aws-elasticbeanstalk-ec2-role as your instance profile. Allow creating a new aws-elasticbeanstalk-service-role.
- Launch your application. You can continue configuration while you wait for it to launch.
- Select 'Configuration', select 'Software Configuration', add the following environment variables from database.yml with their correct values.
- Note that this script is used automatically by AWS EB to run migrations on deployment. You can add your own scripts too.
- Setup CI with CodeShip (see section above)
- Create a branch for deployment. i.e.
git checkout -b deploy
- Setup a deployment pipeline in Codeship, and select Amazon Elastic Beanstalk.
- Create an S3 bucket if you don't already have one, make a directory to store your builds, and set the path on the Codeship configuration page. i.e.
mybucketname/my-boilerplate-rails-api-json-directory
. See documentation. NOTE: Make sure your S3 instance is under the same region as your Elastic Beanstalk service! - Copy AWS access key info from the
Setting up AWS EB
section to the Codeship config page. - Fill out the rest of the config page and submit.
- Push to your configured branch, your app should deploy. Check the Codeship and AWS EB dashboard for error messages. NOTE: I've had issues with non-descriptive error messages on initial deploys. However, I resolved this by manually uploading the .zip file created by Codeship (and saved on your configured S3 bucket) directly to the AWS EB application using the AWS Web GUI. Afterward, Codeship deploys successfully from then on.
The expectation is that you'll fork this template to make your own project and will potentially need to sync using the following procedure: https://help.github.com/articles/syncing-a-fork/