SlyAPI-FSharp


Welcome to SlyAPI F#!

🚧 This library is an early work in progress! Breaking changes may be frequent.

This is a base library used by some of my other projects for wrapping web APIs. Currently, that's just the following:

The goal of this library is to provide easy and readible models for creating higher-level libraries. It is also available in Python!.

Features

Installation

The package is available on NuGet. You can add it your project with the following command:

dotnet add package net.dunkyl.SlyAPI

Before you continue

This package does not implement any particular API. If you are looking to just use an API, you should look at the packages that use this library or recommendations for the API's documentation.

Basic Usage

To get started, subclass the net.dunkyl.SlyAPI.WebAPI type and implement it's BaseURL and UserAgent properties. This example uses the OpenWeatherMap API, and implements just one endpoint.

open System
open net.dunkyl.SlyAPI

type Units = Standard (* Kelvin *) | Imperial | Metric

type CityWeather = {
    Name: string
    Main: {| Temp: float |}
    Weather: {| Description: string |} list
}

type OpenWeather (key: string) =
    inherit WebAPI(QueryAPIKey("appid", key))
    
    override _.BaseURL = Uri "https://api.openweathermap.org/data/2.5"
    override _.UserAgent = "YourWeatherAppLibrary/0.99.0"

    /// Get the current weather of a city.
    /// Location format: `City,Country` or `City,State,Country`
    /// where State and Country are ISO3166 codes.
    member this.City (location: string, units: Units): CityWeather Call =
        this.Get (urlQuery "weather" [ "units", units; "q", location ]) ()

For each endpoint I reccomend the use of tupled, rather than curried, arguments. Some APIs have overloaded endpoints and C# can't use curried form as ergonomically.

Happy coding!

namespace System
type Units = | Standard | Imperial | Metric
union case Units.Standard: Units
union case Units.Imperial: Units
union case Units.Metric: Units
type CityWeather = { Name: string Main: {| Temp: float |} Weather: {| Description: string |} list }
CityWeather.Name: string
Multiple items
val string: value: 'T -> string

--------------------
type string = String
CityWeather.Main: {| Temp: float |}
Multiple items
val float: value: 'T -> float (requires member op_Explicit)

--------------------
type float = Double

--------------------
type float<'Measure> = float
CityWeather.Weather: {| Description: string |} list
type 'T list = List<'T>
Multiple items
type OpenWeather = new: key: string -> OpenWeather member City: location: string * units: Units -> 'a override BaseURL: 'a override UserAgent: 'a

--------------------
new: key: string -> OpenWeather
val key: string
Multiple items
type Uri = interface ISerializable new: uriString: string -> unit + 6 overloads member Equals: comparand: obj -> bool member GetComponents: components: UriComponents * format: UriFormat -> string member GetHashCode: unit -> int member GetLeftPart: part: UriPartial -> string member IsBaseOf: uri: Uri -> bool member IsWellFormedOriginalString: unit -> bool member MakeRelative: toUri: Uri -> string member MakeRelativeUri: uri: Uri -> Uri ...
<summary>Provides an object representation of a uniform resource identifier (URI) and easy access to the parts of the URI.</summary>

--------------------
Uri(uriString: string) : Uri
Uri(uriString: string, creationOptions: inref<UriCreationOptions>) : Uri
Uri(uriString: string, uriKind: UriKind) : Uri
Uri(baseUri: Uri, relativeUri: string) : Uri
Uri(baseUri: Uri, relativeUri: Uri) : Uri