Week | Activity |
---|---|
1 | Prepare Environment |
2 | Implement Milestone 1 API |
3 | Implement Milestone 2 API |
4 | Implement Encryption, Authentication & Access Control and Unit Tests (Milestone 3) |
5 | Complete Unit Tests for Full Coverage (Milestone 4) |
6 | Test Scaling (Milestone 5) |
7 | Test Performance (Mileston 6) |
8 | Test Reliability (Mielstone 7) |
Recommendations in the following references were used as a general guideline while definig these API specs.
API URL requests have the following components which are supplied by the client
For example, GET http://api.example.com/v1/drivers?count=30
In response, the API returns the following
In addition, there may be Headers in both the request and the response.
Currently supported versions of the API and their release date are provided below. All API calls should be prefixed with
the version number GET /VERSION/cars
even though the version number is not included in the documentation of each
API call.
v1
(should be used for VERSION
in the example call above)For example, GET http://api.example.com/v1/drivers?count=30
All resources are named plural (cars
instead of car
) to avoid confusion. No singular references anywhere.
While the API might currently accept some singular versions, that capability will be deprecated. We currently support
the following resources.
Resources that have a relationship to each other can be used as a sub-resource within a URI. For example /drivers/:driverId/cars
identifies the cars for a particular driver while /cars
identifies the global list of cars.
drivers
refers to drivers in the system.
passengers
refers to passengers in the system.
cars
refers to cars in the system. Cars belong to drivers and cannot exist without a driver.
Parameter | Current Applicable Resources | Description |
---|---|---|
count |
all | When returning a list of items, this specifies the maximum elements to return. For example GET /cars?count=100 returns the first hundred cars even if there are more cars in the system |
offsetId |
all | The ID of the last resource already retrieved from a matching list. When provided, server returns resources after this matching element. This is useful in combination with count to get the next page of a list of elements |
sort |
all | Specify the field by which results should be ordered |
sortOrder |
all | Used in combination with sort , it specifies the order in which to return the elements. asc is for asending or desc for descending. Default value is asc except for a time-based sort field in which case the default values is desc |
Note: In this implementation, only support one field for sort
and sortOrder
GET
GET
is used to retrieve either a list of resources or a single resource at a specific URI.POST
POST
is used to create a new resource on the system.POST
is used to create multiple resources (such as adding multiple cars to a driver. We will not do it in this project).POST
is the only method that returns 201 Created
on success.PUT
PUT
is used to replace an entire resource at a URI.PUT
since we mostly update specific properties (see PATCH
below)PUT
currently cannot be applied in bulk to a list of resourcesPATCH
PATCH
is used to update parts of a resource at a URI.PATCH
currently cannot be applied in bulk to a list of resourcesPATCH
implementation is not compliant with standards but is consistent with generally-used convention.DELETE
DELETE
is used to remove a resource from the systemDELETE
cannot be applied in bulk to a list of resourcesStatus
For all successful calls, the return status is 2XX
POST
, the success status code is 201 Created
200 OK
In case of errors, specify the appropriate return status code.
Content-Type
application/json
In addition to providing one of the error Status Codes mentioned above, the Response Body will contain a JSON object with details of the error.
{
"statusCode": number // Sames as HTTP status code
"errorCode": number // A more detailed error code
"errorMessage": string // human readable error message
}
Following are two types of responses that are returned by the drivers
resources.
{
"id": GUID,
"firstName" : String(50),
"lastName" : String(50),
"emailAddress" : String(50), Valid Format,
"password" : String(20, Min 8)
"addressLine1" : String(100),
"addressLine2" : String(100) - Optional,
"city" : String(50),
"state" : String (2, Min 2),
"zip" : String(5, Min 5)
"phoneNumber" : String - XXX-XXX-XXXX
"drivingLicense" : String(16)
"licensedState" : String(2)
}
[
{
"id": GUID,
"firstName" : String,
"lastName" : String
...
...
}, ...
]
Returns the list of all drivers in the system.
Creates a new driver in the system with the object that is passed to it. All fields in the body below are required. This call returns
an modified JSON containing the internally generated id
and other properties populated by the system.
On failure, this will generate a 400 Bad Request
with a description of the failure.
{
"firstName" : String,
"lastName" : String
...
...
}
Returns a driver matching the provided ID. For example, GET /VERSION/drivers/770877af-7d08-447a-8add-ccfd507ce170
will return a JSON representing the driver with that id.
{
"id": GUID,
"firstName" : String,
"lastName" : String
...
...
}
This will allow partial updates of specific fields in the driver. For example, callingPATCH /VERSION/drivers/0db87174-4e11-4369-a8fd-8339ed3abd37
with the first Request Body below
will update firstName
property of the driver in the JSON Body. The id
field in the body is optional,
though if present, it will have to match the one in the URL.
This will return a 200 OK
if the update was successful. If the id
or any field in the body conflicts with the request,
a 404 NotFound
will be thrown with the reason.
The response will contain the updated driver.
{
"firstName": "John"
}
or
{
"firstName": "John",
"lastName": "Doe"
...
...
}
This deletes a driver with the given Id from the system
For example, DELETE /VERSION/drivers/0db87174-4e11-4369-a8fd-8339ed3abd37
will delete the driver and return the json back for confirmation with a 200 OK
Following are two types of responses that are returned by the Passengers
resources.
{
"id": GUID,
"firstName" : String(50),
"lastName" : String(50),
"emailAddress" : String(50), Valid Format,
"password" : String(20, Min 8)
"addressLine1" : String(100),
"addressLine2" : String(100) - Optional,
"city" : String(50),
"state" : String (2, Min 2),
"zip" : String(5, Min 5)
"phoneNumber" : String - XXX-XXX-XXXX
}
[
{
"id": GUID,
"firstName" : String,
"lastName" : String
...
...
}, ...
]
Returns the list of all Passengers in the system.
Creates a new passenger in the system with the object that is passed to it. All fields in the body below are required. This call returns
an modified JSON containing the internally generated id
and other properties populated by the system.
On failure, this will generate a 400 Bad Request
with a description of the failure.
{
"firstName" : String,
"lastName" : String
...
...
}
Returns a passenger matching the provided ID. For example, GET /VERSION/passengers/770877af-7d08-447a-8add-ccfd507ce170
will return a JSON representing the passenger with that id.
{
"id": GUID,
"firstName" : String,
"lastName" : String
...
...
}
This will allow partial updates of specific fields in the passenger. For example, callingPATCH /VERSION/passengers/0db87174-4e11-4369-a8fd-8339ed3abd37
with the first Request Body below
will update firstName
property of the passenger in the JSON Body. The id
field in the body is optional,
though if present, it will have to match the one in the URL.
This will return a 200 OK
if the update was successful. If the id
or any field in the body conflicts with the request,
a 404 NotFound
will be thrown with the reason.
The response will contain the updated passenger.
{
"firstName": "John"
}
or
{
"firstName": "John",
"lastName": "Doe"
...
...
}
This deletes a passenger with the given Id from the system
For example, DELETE /VERSION/passengers/0db87174-4e11-4369-a8fd-8339ed3abd37
will delete the passenger and return the json back for confirmation with a 200 OK
Following are two types of responses that are returned by the cars
resources. For this week’s implementation, we will ignore that Cars belong to Drivers and simply implement them as a top-level resource.
{
"id": GUID,
"make": String(50),
"model": String(50),
"license" : String(10),
"carType" : String(10),
"maxPassengers" : number,
"color" : String(20),
"validRideTypes" : String(16) Array // Values are ECONOMY, PREMIUM, EXECUTIVE
}
[
{
"id": GUID,
"make": String(50),
"model": String(50),
...
...
}, ...
]
Returns the list of all Cars in the system.
Creates a new car in the system with the object that is passed to it. All fields in the body below are required. This call returns
an modified JSON containing the internally generated id
and other properties populated by the system.
On failure, this will generate a 400 Bad Request
with a description of the failure.
{
"make": String(50),
"model": String(50),
...
...
}
Returns a car matching the provided ID. For example, GET /VERSION/cars/770877af-7d08-447a-8add-ccfd507ce170
will return a JSON representing the car with that id.
{
"id": GUID,
"make": String(50),
"model": String(50),
...
...
}
This will allow partial updates of specific fields in the car. For example, callingPATCH /VERSION/cars/0db87174-4e11-4369-a8fd-8339ed3abd37
with the first Request Body below
will update make
property of the car in the JSON Body. The id
field in the body is optional,
though if present, it will have to match the one in the URL.
This will return a 200 OK
if the update was successful. If the id
or any field in the body conflicts with the request,
a 404 NotFound
will be thrown with the reason.
The response will contain the updated car.
{
"make": "Ford"
}
or
{
"make": "Ford",
"model": "Explorer",
...
...
}
This deletes a car with the given Id from the system
For example, DELETE /VERSION/cars/0db87174-4e11-4369-a8fd-8339ed3abd37
will delete the car and return the json back for confirmation with a 200 OK
Following are two types of responses that are returned by the rides
resources. For this week’s implementation, we will ignore that rides have Driver, Car, Passenger and Route Points, and simply implement them as a top-level resource.
{
"id": GUID,
"rideType": String(16) // Values are ECONOMY, PREMIUM, EXECUTIVE
"startPoint" : { lat: Decimal, long: Decimal }
"endPoint": { lat: Decimal, long: Decimal }
"requestTime" : Number (Timestamp)
"pickupTime" : Number (TimeStamp)
"dropOffTime" : Number, (TimeStamp)
"status" : String [REQUESTED, AWAITING_DRIVER, DRIVE_ASSIGNED, IN_PROGRESS, ARRIVED, CLOSED]
"fare": Decimal,
}
[
{
"id": GUID,
"rideType": String(16) // Values are ECONOMY, PREMIUM, EXECUTIVE
"startPoint" : { lat: Decimal, long: Decimal }
...
...
}, ...
]
Returns the list of all Rides in the system.
Creates a new ride in the system with the object that is passed to it. All fields in the body below are required. This call returns
an modified JSON containing the internally generated id
and other properties populated by the system.
On failure, this will generate a 400 Bad Request
with a description of the failure.
{
"rideType": "ECONOMY";
"startPoint" : { lat: 34.5, long: 56.7 }
...
...
}
Returns a ride matching the provided ID. For example, GET /VERSION/rides/770877af-7d08-447a-8add-ccfd507ce170
will return a JSON representing the ride with that id.
{
"id": GUID,
"rideType": "ECONOMY";
"startPoint" : { lat: 34.5, long: 56.7 }
...
...
}
This will allow partial updates of specific fields in the car. For example, callingPATCH /VERSION/rides/0db87174-4e11-4369-a8fd-8339ed3abd37
with the first Request Body below
will update rideType
property of the ride in the JSON Body. The id
field in the body is optional,
though if present, it will have to match the one in the URL.
This will return a 200 OK
if the update was successful. If the id
or any field in the body conflicts with the request,
a 404 NotFound
will be thrown with the reason.
The response will contain the updated ride.
{
"rideType": "ECONOMY";
}
or
{
"rideType": "ECONOMY";
"startPoint" : { lat: 34.5, long: 56.7 }
...
...
}
This deletes a ride with the given Id from the system
For example, DELETE /VERSION/rides/0db87174-4e11-4369-a8fd-8339ed3abd37
will delete the ride and return the json back for confirmation with a 200 OK
The following new API end points will allow cars to be created and managed in the context of a driver.
Other actions like GET
on a single car, PUT
and DELETE
will use the /cars
end point.
Returns the list of all Cars associated with the driver in the system.
Creates a new car in the system associated with the specified driver whose ID is given.
The car is created from the object that is passed to it. All fields in the body below
are required. This call returns
an modified JSON containing the internally generated id
and other properties populated by the system.
On failure, this will generate a 400 Bad Request
with a description of the failure.
{
"make": String(50),
"model": String(50),
...
...
}
Returns a list of rides associated with the passenger.
Returns a list of rides associated with the passenger.
You will delete the following methods (Note: You can repurpose this code for other parts of this milestone)
POST /cars
since you can no longer create cars that are not associated witha driverReturns the a single element array containing the driver associated with the car
Enhance the ride request object to allow for creation with additional references.
{
"id": GUID,
"rideType": String(16) // Values are ECONOMY, PREMIUM, EXECUTIVE
"startPoint" : { lat: Decimal, long: Decimal }
"endPoint": { lat: Decimal, long: Decimal }
"requestTime" : Number (Timestamp)
"pickupTime" : Number (TimeStamp)
"dropOffTime" : Number, (TimeStamp)
"status" : String [REQUESTED, AWAITING_DRIVER, DRIVE_ASSIGNED, IN_PROGRESS, ARRIVED, CLOSED]
"fare": Decimal,
"driverId" : GUID of the driver,
"carId" : GUID of the car,
"passengerId" : GUID of the passenger
}
Creates a route point on the route taken for the ride. This allows a client to set a series of points on
the route that the driver takes for a given ride.
{
timestamp: Number (TImestamp)
lat: Decimal,
long: Decimal
}
Gets the complete list of route points ordered by timestamp (ascending order)
Gets the latest (by timestamp) single route point
In this milestone, you will implement encryption of key data in the system,
add authentication and provide access control by implementing two roles
for users.
Study and compare encryption and hashing by reading about them on the web.
Below are some useful links for this.
Once done, do the following to complete this port of the Milestone.
POST
method must accept a stringGET
methods for passengers
and drivers
so that the passwordModify your code to do the following
sessions
API described below. Both drivers and passengers authenticateImplement the following
POST
methods for drivers
and passengers
so that you cannot havePOST
method is called rides
and cars
, including POST
for cars
within thedrivers
resource. Only drivers can call POST
method on cars
and, either passengers or drivers can callPOST
methods on rides
. For now, you don’t have to restrict that a driver can onlyAuthenticate a user with the following request body
{
"email": "john@doe.com",
"password" : "somepassword"
}
Authenticates the user against the driver and passenger data and returns the following response body
{
"token" : "787897dasd78d7f9s7df98sdf89sd7f89sd7f89sdf"
}
The token should be hashed and encrypted, and contain the user’s ID and an expiration date.
In this milestone, you will implement unit tests for all APIs that you created in the
previous milestones. Coverage of ALL APIs is required for full credit.
In this milestone, you will do load testing on the APIs that you created in the
previous milestones.
n1-standard-1
)