/asana

a simple api application done for interview by asana

Primary LanguageRuby

README

Table of Contents

  1. Introduction
  2. Project Design
  3. Features
  4. Endpoints
  5. Error Handling
  6. Installation
  7. Things To Improve

Introduction

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.

Project Design

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.

Features

  • Authentication built with ruby-jwt library
  • Geocoding perfomed with geocoder library
  • Rails as api only with potsgresql
  • Complete test suite written with rspec, rspec-mocks and factory-bot.

Endpoints

Registrations - User signs up with the /api/v1/users/registrationsendpoint 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:

  1. The token is invalid or expired
  2. Geocoder Api limit is reached
  3. Geocoder Api - Location not found
  4. Other errors will return status 500 - Internal Server Error

Error Handling

Geocoder

I quote the Geocoder documentation:

By default Geocoder will rescue any exceptions raised by calls to a geocoding service and return an empty array.

  1. Exception Geocoder::OverQueryLimitError
    The http request has response body {"errors": ["Geocoder API daily limit reached"]} with status 403.
  2. The other exceptions follow the standard Geocoder behaviour, the response has status 404 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?

  1. 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.
  2. 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 status 500 and internal server error an appropriate response. The error will not break the client functionality, as long as the client handles this scenarios.

Json Web Token

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"]}.

Installation Instructions

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.