Feedback for an API-wrapper

Hi there, I discovered Julia just a couple of hours ago. And wanted to give it a try.

Could you give me feedback for my AccuWeather API-wrapper. I still have to find a way to make a few arguments optional. Some additions to strings can be coupled togethe, but for simplicity I have left them this way (it makes it easy to copy/paste a function for other API-methods). The ‘make-API-call’ functions uses HTTP.requests to send a GET-request and scans the response for errors.

function get_forecast(apikey::String, timespan::String, time::Int64, locationKey::String, language::String, details::Bool, metric::Bool)
    # Daily/Hourly forecasts for a specific location. Forecast searches require a location key. Please use the Locations API to obtain the location key for your desired location. By default, a truncated version of the hourly forecast data is returned. The full object can be obtained by passing "details=true" into the url string.

    url = "http://dataservice.accuweather.com/forecasts/v1/"

    # Add required parameters to the URL
    url = url * timespan * "ly"
    # Accepted values: day hour
    
    url = url * string(time) * timespan * "/"
    # Accepted values:
    # - Days: 1/5/10/15
    # - Hours: 1/12/24/72/120
    #   Example: If "timespan" is set to "day" and "time" to 10, it gets the forecast for 15 days.
    
    url = url * string(locationKey)
    url = url * "?apikey=" * apikey

    # Add optional parameters to the URL
    if language != Nothing url = url * "&language=" * language end
    if details == true url = url * "&details=true" end
    if metric == true url = url * "&metric=true" end
    

    return make_API_call(url)
end

Welcome!

My first suggestion would be to use the type system to make the time arguments easier to specify. Your current function asks for a timespan::String and a time::Int64, but it’s not clear from those types what inputs are actually allowed. For example, it looks like I can do "day", 5 and "hour", 120, but doing "hour", 18 or "minute", 60 will likely cause an error.

You could make this function friendlier by taking in a dedicated type representing an amount of time. Julia has some useful types in the built-in Dates package. For example:

julia> using Dates
                                                                                                                                                                                                                                                                                                                                      
julia> Day(5)
5 days                                                                                                                                                                                                                                                                                                                                

julia> Hour(12)
12 hours

You could write a function which takes in a time range given in hours or days like this:

function get_forecast(apikey, duration::Union{Hour, Day}, <your other arguments here>)
  url = <your code here>
  url = url * url_date_string(duration)
  <more code here>
end

And then you could define url_date_string like this:

url_date_string(d::Day) = "$(d.value)daily"

url_date_string(h::Hour) = "$(h.value)hourly"

for example:

julia> url_date_string(Day(5))
"5daily"

julia> url_date_string(Hour(12))
"12hourly"

The advantage of this representation is that you can be extremely clear about what kinds of date ranges are allowed.

1 Like