OpenAPI Client Provider
OpenApiClientProvider is a generative F# Type Provider, built on top of Microsoft.OpenApi.Readers schema parser that supports 3.0 and 2.0 schema formats.
open SwaggerProvider
let [<Literal>] Schema = "https://petstore.swagger.io/v2/swagger.json"
type PetStore = OpenApiClientProvider<Schema>
let client = PetStore.Client()Parameters
OpenApiClientProvider supports the following configuration parameters
| Parameter | Description |
|---|---|
Schema | Url or Path to Swagger schema file. |
IgnoreOperationId | Do not use operationsId and generate method names using path only. Default value false. |
IgnoreControllerPrefix | Do not parse operationsId as <controllerName>_<methodName> and generate one client class for all operations. Default value true. |
PreferNullable | Provide Nullable<_> for not required properties, instead of Option<_>. Defaults value false. |
PreferAsync | Generate async actions of type Async<'T> instead of Task<'T>. Defaults value false. |
SsrfProtection | Enable SSRF protection (blocks HTTP and localhost). Set to false for development/testing. Default value true. |
IgnoreParseErrors | Continue generating the provider even when the OpenAPI parser reports validation errors (e.g. vendor extensions or non-strictly-compliant schemas). Warnings are printed to stderr. Default value false. |
More configuration scenarios are described in Customization section
Security (SSRF Protection)
By default, SwaggerProvider blocks HTTP URLs and localhost/private IP addresses to prevent SSRF attacks.
For development and testing with local servers, disable SSRF protection:
// Development: Allow HTTP and localhost
type LocalApi = OpenApiClientProvider<"http://localhost:5000/swagger.json", SsrfProtection=false>
// Production: HTTPS with SSRF protection (default)
type ProdApi = OpenApiClientProvider<"https://api.example.com/swagger.json">Warning: Never set SsrfProtection=false in production code.
Non-Strictly-Compliant Schemas (IgnoreParseErrors)
Some OpenAPI schemas generated by tools such as NSwag may include extensions or properties that are technically invalid (e.g. nullable: true at the parameter level). By default, SwaggerProvider aborts with an error when the Microsoft.OpenApi parser reports such validation errors.
Set IgnoreParseErrors=true to continue generating the type provider despite these errors. Validation warnings are printed to stderr so they remain visible:
// NSwag-generated schema with non-standard nullable annotations
type MyApi = OpenApiClientProvider<"https://example.com/swagger.json", IgnoreParseErrors=true>Note: Only use IgnoreParseErrors=true when you trust the schema source. Suppressing errors may hide genuine schema problems that could affect the generated client.
CancellationToken Support
Every generated method automatically includes an optional cancellationToken: CancellationToken parameter (defaults to CancellationToken.None). This allows you to cancel long-running HTTP requests:
open System
open System.Threading
open SwaggerProvider
let [<Literal>] Schema = "https://petstore.swagger.io/v2/swagger.json"
type PetStore = OpenApiClientProvider<Schema>
let client = PetStore.Client()
task {
// Cancel after 5 seconds
use cts = new CancellationTokenSource(TimeSpan.FromSeconds(5.0))
let! pet = client.GetPetById(42L, cancellationToken = cts.Token)
printfn $"Pet: {pet}"
}
|> _.ResultSample
open System
open System.Net.Http
open SwaggerProvider
let [<Literal>] Schema = "https://petstore.swagger.io/v2/swagger.json"
// By default provided methods return Task<'a>
// and use Option<'a> for optional params
type PetStore = OpenApiClientProvider<Schema>
[<EntryPoint>]
let main argv =
// `UseCookies = false` is required if you use Cookie Parameters
let handler = new HttpClientHandler(UseCookies = false)
// `BaseAddress` uri should end with '/' because TP generates relative URIs
let baseUri = Uri("https://petstore.swagger.io/v2/")
use httpClient = new HttpClient(handler, true, BaseAddress = baseUri)
// You can provide your instance of `HttpClient` to the provided API client
// or change it any time at runtime using `client.HttpClient` property
let client = PetStore.Client(httpClient)
task {
// Create a new instance of the provided type and add to store
let pet = PetStore.Pet(Id = Some(24L), Name = "Shani")
do! client.AddPet(pet)
// Request data back and deserialize to the provided type
let! myPet = client.GetPetById(24L)
printfn "Waw, my name is %A" myPet.Name
}
|> Async.AwaitTask
|> Async.RunSynchronously
0