🚧 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!.
- Easy to use models for creating API wrappers.
- Automatic serialization and deserialization of JSON data.
- OAuth2 support.
- Async!
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.
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