Estimate the scale of the system you are going to design...
Given that we are leveraging an external API, having Rest calls for typical requests alongside sockets or SDKs like Firebase that are available for emergency notifications would be ideal.
The primary API call would be the following REST API endpoing
GET /batch-weather
{
locations : [
{
city: ""
country: ""
},
]
}
This endpoint can be used to obtain data for a series of locations depending on how many places a user has subscribed to.
A secondary endpoint can be used to retrieve weather for a specific location that a user is looking up, or for the user's direct current location.
GET /weather?long=""&lat=""
This one will be specifically given details from whatever location a user is attempting to search up directly.
While the weather data we wish to retrieve will all be provided by the external API that was mentioned as part of our assumption, there will still remain a need to minimize the number of calls directly made to said external API. This will be to minimize costs that will be attributed through use of the external API. In order to do so, it would be best to leverage a cache of sorts to hold onto commonly used location data. As such an LRU cache can be held in place with a somewhat short time to live since weather data tends to shift at a moments notice.
The cache type we wish to use can either be in the form of memcached or Redis, either one can work here. For the cache itself, the storage will be in the form of key-value pairs with the keys being a mix of longitude + latitude or city + country and the value of course being the response that has been retrieved.
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
For the end to end flow, a user will make an unauthenticated HTTPS request to the service. They'll send along their longitude and latitude coordinates in the GET request. A stateless server will accept the request and make a read-through request to Redis. If there is fresh information in the cache. If there's a data point in the cache that is within the acceptable range of a user's location, then we will return the data to the server. The server can then return this data directly to the user.
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Explain any trade offs you have made and why you made certain tech choices...
Our reliance on the external API is a single point of failure. If the external API goes down, our service goes down as well.
The user request volume is a potential bottleneck as well if there's a burst of traffic that our servers won't be able to handle.
If we hit the weather API rate limit, we can consider serving users weather information close to location they requested. For example, we can consider a radius of 1 mile from the requested location as information that's accurate enough and serve that information to users. We can also consider leveraging multiple weather providers so we have fallback options in case one fails.
We can leverage DNS routing to route users to their closest geographical weather service. This will help alleviate the user request volume. We can consider replicating more services in dense, metropolitan areas to accommodate for areas that might experience higher volume of requests.
We will integrate the service with logging capabilities so we are able to alert on server and general region unavailability.