This application is a simple messenger API that allows logging messages between two users of the system.
You can find this application deployed to Heroku if you would prefer to interact with a web-accessible version of the application.
See below for setup instructions.
To save on time, my approach to building and testing this application was to focus on having a robust acceptance test suite for the messages endopint and forgoing tests on everything else. In a real world scenario, I would have unit tests in place for anything non-trivial.
The messages endpoint has a few extra features that weren't requested by the requirements document but that I thought might be useful and were easy additions.
This application is housed within a standard Rails application. You'll see some config files around that might not make sense since this is an API application (i.e. yarn.lock, babel.config.js, node_modules, etc), but I left them in place just in case there's a need to build some kind of UI on top of this project later.
All notable code files are under app
, and everything else is configuration or Rails boilerplate. Significant code files are bolded.
The base class for serialization. Defines a small API for declaring attributes and overriding methods. There are
some features in this file that are currently unused, but are features that I've found very helpful in building
APIs (notably, the :include
option, which can help with performance by reducing payload size).
As an aside, I think this file has the most room for improvement. It's doing some clever things, isn't the most readable, and despite being of critical importance to the entire API, it has no unit tests. This file poses the highest risk to change, so this would be the first place I would start with backfilling tests.
Responsible for creating messages, and will also create the sender and recipient by username if they don't already exist in the system. I generally cover service objects pretty thoroughly with unit tests.
As an aside, I'm a big fan of service objects (aka use-case objects, domain objects, actors, interactors, etc) when an atomic operation has more than one step.
Not used (but left in place just in case):
This project is set up on CircleCI and is automatically deployed to Heroku on a green build of the master branch.
These setup instructions assume that you have Ruby installed, and that it does not require sudo
to install
dependencies. If you need to install Ruby, my personal favorite ruby management utilities are
https://github.com/postmodern/chruby and https://github.com/postmodern/ruby-install.
This application assumes Ruby version 2.5.3. You'll also need to have a PostgreSQL database server running. The database
configuration assumes a postgres user with the same name as your system username ($ whoami
) and no password, but you can tweak
config/database.yml if you need different settings.
The following command should install all dependencies, create your development and test databases and seed the dev database.
$ bin/setup
You should see some output that looks something like:
== Installing dependencies ==
The Gemfile's dependencies are satisfied
== Preparing database ==
Created database 'messenger_api_development'
Created database 'messenger_api_test'
Seeding users
Seeding messages
== Running specs ==
Messages
GET /api/v1/messages
Listing messages for all users
- Limits messages to 100
- Limits messages to those created in the last 30 days
When requesting messages for a specific sender
Listing messages for a specific sender
When requesting messages for a specific recipient
Listing messages for a specific recipient
When requesting messages for a specific conversation
Listing messages for a specific conversation
- Limits messages to 100
- Limits messages to the last 30 days
POST /api/v1/messages
When the user ids are known
Creating a message in a conversation between two users
When the user ids are not known
Creating a message between two usernames
When users already exist by the given usernames
- It finds existing users
With invalid attributes
Attempting to create a message with invalid attributes
PUT /api/v1/messages/:id
When marking a message as read
Updating a message's "read" status
Finished in 1.79 seconds (files took 4.33 seconds to load)
13 examples, 0 failures
Now, to start an application server on port 3000:
$ bundle exec rails s
Here's an example cURL command to get you started:
$ curl --header 'Accept: application/json' http://localhost:3000/api/v1/messages
API Documentation can be accessed at http://localhost:3000/api/docs
If you would like to run the tests again:
$ bundle exec rspec spec --format=doc
If you need to regenerate the api documentation for any reason:
$ bundle exec rake docs:generate
Enjoy! ❀