/appointment-scheduler

A Spring Boot demo application for scheduling appointments

Primary LanguageJavaApache License 2.0Apache-2.0

Travis Build Status

A demo project for showcasing how to use Spring Boot to implement RESTful web services by creating a small appointment scheduler application.

Technologies

  • Java 11
  • JUnit 5
  • Spring Boot 2.1
  • Postgres 10
  • Docker 18.09
  • Docker Compose 3.7

Quickstart

How to Build

Run the following from your command line

mvn clean install
docker-compose up --detach

Verify docker-compose starts - you should see the following

Starting appointment-scheduler_db_1 ... done
Recreating appointment-scheduler_api_1 ... done

Check docker for the running container information

docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS                    PORTS                    NAMES
2e440df7141b        nwarabak/appointment-scheduler:1.0   "java -jar /usr/shar…"   15 seconds ago      Up 13 seconds             0.0.0.0:8080->8080/tcp   appointment-scheduler_api_1
34860ef33560        postgres:10                          "docker-entrypoint.s…"   6 minutes ago       Up 14 seconds (healthy)   0.0.0.0:5432->5432/tcp   appointment-scheduler_db_1

Ensure the the application is alive and happy by calling the health API.

Appointment Autogen

You'll also notice that as the application runs, it will automatically create new appointments at random intervals. This is to help exercise the endpoints without bothering with cURL / Postman / ARC / etc. while demonstrating the elegance of Spring profile composition.

If you wish to not auto-create appointments, simply remove the random-scheduler Spring profile from docker-compose.yml.

For more detail around this feature, please see com.warabak.appointmentscheduler.services.RandomScheduler.java.

APIs

Health

GET /health

Checks the health of the application

curl -s 'http://localhost:8080/health' | jq .
{
  "health": "green"
}

Appointments

GET /appointments

Lists all existing appointments

curl -s 'http://localhost:8080/appointments' | jq .
[
  {
    "id": 1,
    "createdAt": "2019-02-24T19:11:51.040728-05:00",
    "scheduledDate": "2019-05-05T00:08:43.487-04:00",
    "durationInMinutes": 90,
    "doctorFullName": "Benedict Hermann",
    "status": "Available",
    "price": 177.37
  },
  {
    "id": 2,
    "createdAt": "2019-02-24T19:11:52.911455-05:00",
    "scheduledDate": "2019-08-05T23:51:16.157-04:00",
    "durationInMinutes": 50,
    "doctorFullName": "Miss Gwyneth Hegmann",
    "status": "Available",
    "price": 859.68
  },
  {
    "id": 3,
    "createdAt": "2019-02-24T19:11:53.651012-05:00",
    "scheduledDate": "2019-03-09T04:04:42.276-05:00",
    "durationInMinutes": 85,
    "doctorFullName": "Dia Parisian",
    "status": "Booked",
    "price": 684.83
  },
  {
    "id": 4,
    "createdAt": "2019-02-24T19:11:54.306298-05:00",
    "scheduledDate": "2019-12-13T15:39:28.278-05:00",
    "durationInMinutes": 130,
    "doctorFullName": "Rhett Denesik Sr.",
    "status": "Booked",
    "price": 479.36
  },
  {
    "id": 5,
    "createdAt": "2019-02-24T19:11:54.946156-05:00",
    "scheduledDate": "2020-02-11T19:11:40.226-05:00",
    "durationInMinutes": 60,
    "doctorFullName": "Glynda Predovic",
    "status": "Booked",
    "price": 398.74
  }
]

GET /appointments?start={date}&end={date}

Lists all existing appointments between the given start and end dates. Both dates must be provided and must be an ISO-8601 date time format

curl -s 'http://localhost:8080/appointments?start=2019-01-01T00:00:00.000-00:00&end=2019-06-01T00:00:00.000-00:00' | jq .
[
  {
    "id": 3,
    "createdAt": "2019-02-24T19:11:53.651012-05:00",
    "scheduledDate": "2019-03-09T04:04:42.276-05:00",
    "durationInMinutes": 85,
    "doctorFullName": "Dia Parisian",
    "status": "Booked",
    "price": 684.83
  },
  {
    "id": 1,
    "createdAt": "2019-02-24T19:11:51.040728-05:00",
    "scheduledDate": "2019-05-05T00:08:43.487-04:00",
    "durationInMinutes": 90,
    "doctorFullName": "Benedict Hermann",
    "status": "Available",
    "price": 177.37
  }
]

GET /appointments/{id}

Find an appointment by its ID.

curl -s 'http://localhost:8080/appointments/3' | jq .
{
  "id": 3,
  "createdAt": "2019-02-24T19:11:53.651012-05:00",
  "scheduledDate": "2019-03-09T04:04:42.276-05:00",
  "durationInMinutes": 85,
  "doctorFullName": "Dia Parisian",
  "status": "Booked",
  "price": 684.83
}

PUT /appointments/{id}/{status}

Update an appointment's status

curl -s -X PUT 'http://localhost:8080/appointments/3/Available' | jq .
{
  "id": 3,
  "createdAt": "2019-02-24T19:11:53.651012-05:00",
  "scheduledDate": "2019-03-09T04:04:42.276-05:00",
  "durationInMinutes": 85,
  "doctorFullName": "Dia Parisian",
  "status": "Available",
  "price": 684.83
}

POST /appointments

Create a new appointment.

curl -s -d '{"scheduledDate":"2019-03-01T12:30:00+00:00","durationInMinutes":"60","doctorFullName":"Shelby Jahns","status":"Available","price":100}' -H 'Content-Type:application/json' 'http://localhost:8080/appointments' | jq .
{
  "id": 9,
  "createdAt": "2019-02-25T01:09:15.487552Z",
  "scheduledDate": "2019-03-01T12:30:00Z",
  "durationInMinutes": 60,
  "doctorFullName": "Shelby Jahns",
  "status": "Available",
  "price": 100
}

DELETE /appointments/{id}

Delete an appointment by its ID.

curl -s -X DELETE 'http://localhost:8080/appointments/9' | jq .
{
  "id": 9,
  "createdAt": "2019-02-24T20:09:15.487552-05:00",
  "scheduledDate": "2019-03-01T07:30:00-05:00",
  "durationInMinutes": 60,
  "doctorFullName": "Shelby Jahns",
  "status": "Available",
  "price": 100
}

Randomizer

POST /randomizer

Create a randomly-generated experiment.

curl -s -X POST http://localhost:8080/randomizer | jq .
{
  "id": 10,
  "createdAt": "2019-02-25T01:12:10.521149Z",
  "scheduledDate": "2019-10-10T04:18:15.458Z",
  "durationInMinutes": 110,
  "doctorFullName": "Santiago Klocko",
  "status": "Available",
  "price": 675.11
}

Further reading