As a developer, I need a way to get the weather for a specific city via an API.
Additional Assumptions / User Stories:
As a developer, I need a way to get the current weather for a specific city via an API.
As a developer, I need a way to get the 7 day forecast of weather for a specific city via an API.
Stretch (not implemented): As a user, I need a user account to save personalized information about the weather.
As an authenticated user, I need to save cities to my favourites.
As an authenticated user, I need a way to retrieve cities on my favourite list.
I chose Node.js, Typescript & Express as my primary tech stack.
Node.js uses an event driven architecture, because of this it is able to scale to support many client request calls - despite being 'single threaded'. If this were a real world application; it would scale quite well as demand increases. It could also easily be horizontally scaled.
I chose Typescript over Javascript because of type checking, which I feel is an important language feature. It makes the developer experience much more enjoyable, and increases the maintability of code.
I chose Express because it is a fast and minimal web server framework for Node.js.
For the deployment environment I chose to run it in a containerized environment - Docker. Docker provides utilities like automatically restarting services when they go down, as well as recording the console errors into a log. Additionally, it makes the set up of the app incredibly easy if it needs to be set up on a different physical device, which as the service is scaled is an inevitability.
base path = /v1/
weather => GET /weather
Acceptable query parameters:
location=city => If location is not provided returns an error. Else, will return weather data for that city.
type=current|forecast => if not provided both types of information will be returned
interface WeatherResponse {
location: string;
weather: {
current: WeatherData;
forecast: WeatherData[];
}
}
interface WeatherData {
date: Date;
state: WeatherState;
temperature: Temperature;
probabilityOfPrecipitation: number;
}
enum WeatherState {
raining = "raining",
sunny = "sunny",
cloudy = "cloudy",
hailing = "hailing",
snowing = "snowing",
}
interface Temperature {
high: number;
low: number;
}
Stretch (not implemented):
user registration = POST /register => allows user to register an account for the service
user login = POST /login => allows user to log into their account on the service
Add city to their favourite list = POST /favourites => authenticated user sends location data, saved to their favourites list.
Get favourites = GET /favourites => authenticated user gets list of their favourite cities.
Monday, March 30th, 2020
Deployed on Heroku (Free tier - so will be slow to start up)
Design & basic app set up - 2 hours
Implementation - 2.5 hours
Deployment - 0.5 hour
Total - 5 hours
I wrote additional user stories (listed above) that outline some of the assumptions I made about the requirements. In a real world scenario I would have asked stakeholders if they agreed with these user stories and would revise or proceed from there.
I originally planned on having a list of 'valid cities' that the API would support - with the intent to have a list of all major valid cities in North America. Unfortunately, I wasn't able to procure such a list and therefore I felt it better to just leave the location parameter unhandled and return the fake data that would be generated. It does however throw an error if no location is provided.
I had originally planned to tackle the authentication stretch goal, unfortunately I ran out of time to complete this. Instead I decided to tackle the deployment stretch goal.
git clone [email protected]:derrickpersson/city-weather.git
cd city-weather
npm i
npm run build
npm run start
With more time, I would have enhanced the basic infrastructure of the application, adding in features like - consistent logging (with Winston) and a 'catch all' error handler for Express.
Added in 'production' end points like /info & /heath, these are important for monitoring of the application.
Overall I felt it is pretty well outlined - I would have appreciated a quick 5 minute video call to go over the assignment & understand next steps in the hiring process.