JsonVoorhees 1.5.0
Introduction
JsonVoorhees is an api builder that encapsulates all of it's generated code inside of engines. It's essentially an opinionated framework built with rails generators. It comes with common gems, a user model and other common functionality such as token authentication. It builds in a scalable solution for authorizations. All controller actions are before filtered into a method that takes as arguments the current user, the parameters and current object. As a bonus, when the object is ready to be serialized, every attribute and association implements active model serializers include? method. Both controller and serializer consult the corresponding method in the created authorizations gem. This leaves the controller and serializer slim and all of the authorizations in one spot. You can be as granular as you want to be. Since tests are already set up for you, it makes implementing your features a breeze. Enjoy!
Scaffold Use
To install, put this in your main_app and run bundle install.
gem "json_voorhees"
rails g json_voorhees:setup_app
or
rails g json_voorhees:setup_app --fbonly
The latter command will instead create a user from a fb access token in the login process.
Now when you want to create an engine run the below command from the main app. It takes care of mounting the engine, setting up the controllers, routes and gemspecs.
rails g json_voorhees:create_engine [engine name]
Now we can create resources, run the below command from the main_app. Specs will be created and the routes for that resource are setup.
rails g json_voorhees:massive_scaffold [engine name] [resource name] [api_version] [scaffold parameters]
example
rails g json_voorhees:massive_scaffold chat message 1 user_id:integer message:text
Project Flow
- Create main app
- (in main_app root) rails g json_voorhees:setup_app
- (in main_app root) rails g json_voorhees:create_engine [engine name]
- (in main_app root) rails g json_voorhees:massive_scaffold [engine name] [resource name] [api_version] [field:type field:type]
- (in main_app root) Copy migrations to main app and run db migrations in main app like so. "rake railties:install:migrations && rake db:migrate RAILS_ENV=development && rake db:migrate RAILS_ENV=test"
- (in main_app root) Run "rspec" to check for errors
I usually set the app up, and then design the database. I make a list of all the models I need, then separate them into engines. Then I run 20 or so massive scaffolds using "&&". The result is a modular functioning backend that only needs the model relationships wired together. The default tests get you pretty far. It's a pretty good idea to create a script file that contains all of the scaffolds. It's essentially a schema for how to recreate your backend.
Test it out
After creating your rails app and including the json_voorhees gem, cd into your directory and run this command. Explore the files to see what it does for you.
rails g json_voorhees:setup_app --fbonly &&
rails g json_voorhees:create_engine ocean &&
rails g json_voorhees:massive_scaffold ocean atlantic 1 cold:boolean hot:boolean &&
rails g json_voorhees:massive_scaffold ocean pacific 1 fun:boolean description:string &&
rake railties:install:migrations &&
rake db:migrate RAILS_ENV=development &&
rake db:migrate RAILS_ENV=test &&
rake db:migrate RAILS_ENV=production &&
rspec
Gotchas and Reminders
JsonVoorhees is only tested on rails apps from 4 - 4.1.6 but it should work on anything below 4.2. 4.2 finally includes some commonly used gems so it throws an error when JsonVoorhees tries to include it again. I'll write up a list of these offenders later.
After authenticating the user, routes will by default require the users token to be sent with every request. This can be disabled by skipping the filter in the controller. If you want to set the user optionally, call set_hash. It wont return an error if the user can't be authenticated. In addition, every request to the api will need the api token sent with it. It can exist in either the headers or params hash. Look at the settings file in config to see what the default header and keys are. In production, make sure this key is set to something different and remove it from version control.
401s are sent for a number on reasons but if the user is not authenticated it will send a header along with the 401. Check for this header and a 401 to know if a user needs to log in again. Look the api controller to see the defaults.
- Make sure the version of Rails is the same in both engine and app.
- The mailer doesn't need to be set up. For test and development it is set so this doesn't have to be the case but change the environment config file to make it work.
- To use the mailer, make sure to export GMAIL_USERNAME and GMAIL_PASSWORD to your environment. Or you can just overwrite the values in the environment config file.
- To use gmail, your account needs to have an app_password. That is the password that should go on file.
- Account mailer in the people engine needs to be updated with the correct domain as well the host in application.rb config file for production.
- The account controller isn't under the api, forgotten_passwords etc should be implemented on the server.
- To run the generators, sometimes spring will get in your way. If it hangs, run "spring stop"
- Cors may not work the same on all machines and rails versions. If it is acting up in production, if serve static assets is false, it wont find the Rails Static middleware to insert before and it will throw an error.
- For fbonly, make sure you go to the facebook folder and look at the file. You need to set the environment variables FB_APPID1 and FB_SECRET1.
Does not work with Rails 4.2 yet. Byebug is added by default and this generator tries to add it twice so it fails.
Bugs
Serializer doesn't call the correct method for attributes
Future
- Sidekiq
- Paperclip
- Websockets
Emails are sent synchronously for now. I'm waiting for ActiveJob in Rails 4.2 so I can implement that interface and use the sidekiq adapter.