Code Challenge written for Asana Rebel, it consist of an api only rails application with postgresql database.
The application was built with alexreise/geocoder
gem as by email instructions received from the company.
Authentication: The authentication is based on ruby-jwt
, instead of using nsarno/knock
.
My decision was to build a custom solution with ruby-jwt
and to showcase my passion and programming skills.
Geocoder: The geocoding functionalities are built with geocoder
gem, as agreed by email with Asana.
- Authentication built with
ruby-jwt
library - Geocoding perfomed with
geocoder
library Rails
as api only withpotsgresql
- Complete test suite written with
rspec
,rspec-mocks
andfactory-bot
.
Registrations - User signs up with the /api/v1/users/registrations
endpoint with email and password.
The endpoint returns a token
, valid for 12 hours.
The request is available in postman.
Sessions - User signs in with the /api/v1/users/sessions
endpoint with email and password.
The endpoint returns a token
, valid for 12 hours.
The request is available in postman.
Locations - The locations
endpoint /api/v1/users/locations
is protected from authentication.
The request Authorization
header includes the token
, takes an address
query string and returns the latitude
and longitude
.
The request is available in postman.
The application handles the following errors:
- The token is invalid or expired
- Geocoder Api limit is reached
- Geocoder Api - Location not found
- Other errors will return status 500 - Internal Server Error
I quote the Geocoder documentation:
By default Geocoder will rescue any exceptions raised by calls to a geocoding service and return an empty array.
- Exception
Geocoder::OverQueryLimitError
The http request has response body{"errors": ["Geocoder API daily limit reached"]}
with status403
. - The other exceptions follow the standard
Geocoder
behaviour, the response has status404
and body{ errors: ['Location not found']}
.
SocketError
Timeout::Error
Geocoder::RequestDenied
Geocoder::InvalidRequest
Geocoder::InvalidApiKey
Geocoder::ServiceUnavailable
I quote the question from the Asana Challenge:
What happens if we encounter an error with the third-party API integration? Will it also break our application, or are they handled accordingly?
Geocoder::OverQueryLimitError
is given a special behaviour. The client must know the root cause of the error as he may be the one performing too many requests, for example the mobile app is performing 1000 requests each time the user presses a specific bottom, while the client requirements are to perform only 1 request.InvalidApiKey
,ServiceUnavailable
and the other errors are not relevant for the client, which does not need the information and can not fix the disfunctionality. I consider status500
andinternal server error
an appropriate response. The error will not break the client functionality, as long as the client handles this scenarios.
The Json Web Token expires every 12 hours. The client needs to re-authenticate at the /sessions
endpoint.
Malformed or Expired tokens are rescued with JWT::DecodeError
which returns http response status 401
Unauthorized with body {errors: ["Unauthorized, Token invalid or expired"]}
.
ruby version ruby 2.6.5
rails 6.0.0
Include the following environment variables in your ~/.bash_profile
or ~/.zshrc
(depending on the terminal you use):
export SECRET_KEY="1a50650399a031cd088b06742108adf1"
export ASANA_DATABASE_PASSWORD="yourProductionPassword"
You can now install the project
source ~/.bash_profile
source ~/.zshrc
git clone git@github.com:fabriziobertoglio1987/asana.git
cd asana
bundle install
rails db:setup
Run rspec
to run the test suite.
Run rails s
and test with postman request on your local environment.