As part of an interview coding challenge, I was asked to create a simple backend API that returned a list of doctors and their appointments. Before this challenge, I only knew in theory how to create an API-only app in Ruby on Rails and I believe I had followed through a tutorial to create a simple API. This post will cover what I learned from going through the process of reading the Rails documentation and understanding the requirements from the challenge given to me.
First and foremost is to create a Rails API-only app:
$ bundle exec rails new doctors_api --api
The idea will be to create a Rails API with the following routes at the minimum:
GET api/v1/doctors
GET api/v1/doctors/1
POST api/v1/doctors
DELETE api/v1/doctors/1
GET api/v1/doctors/1/appointments
POST api/v1/doctors/1/appointments
DELETE api/v1/doctors/1/appointments/1
Security and authentication protocols aside, this should allow any client to create, view or delete a doctor or appointment resource.
Models
Once the application is ready, next step will be to create a data model and controller for Doctor and Appointment.
$ bundle exec rails g scaffold Doctor first_name:string last_name:string
$ bundle exec rails g scaffold Appointment first_name:string last_name:string visit:datetime
$ bundle exec rails db:create
$ bundle exec rails db:migrate
In app/models/doctor.rb
class Doctor < ApplicationRecord
has_many :appointments, dependent: :destroy
end
In app/models/appointment.rb
class Appointment < ApplicationRecord
belongs_to :doctor
end
Controllers
It’s recommended to organize your API controllers, at best we will move them to their own directory. In this example we move the appointments and doctors controller ruby files to an API directory.
mv app/controllers/*.rb app/controllers/api/v1
The controllers will be doing the brunt of the work of processing the requests using the index, show, create, update, and destroy methods.
Seeding the database
In db/seeds.rb, we will seed sample data to ensure the REST endpoints work as designed.
Doctor.create(first_name: 'John', last_name: 'Smith')
doctor = Doctor.first
Appointment.create(doctor_id: doctor.id, patient_first_name: 'Jane', patient_last_name: 'Doe', visit: 2.hours.ago)
Appointment.create(doctor_id: doctor.id, patient_first_name: 'Jack', patient_last_name: 'Doe', visit: 1.day.ago)
bundle exec rails db:seed will insert the records into the database.
Testing
In a web browser or a REST client, now you test the endpoints
Creating new records for Doctor and Appointment will accept a JSON payload as a POST request
Conclusion
In the end, we achieved our simple goal of a nested REST API. To improve on this setup, in the front-end we can sanitize the inputs before sending requests, insert client information in the HTTP headers to be authenticated in the backend. An example for such an effort is to ensure doctors can only view their own appointments.
Full discretion, while this post has largely been a learning exercise, a full scale REST API will have it’s own set of complexities and design principles that isn’t covered here. Stay tuned for more posts in the future as and when I encounter similar and complex problems in the backend software engineering space.
Top comments (0)