Support F# option type in OpenApi schema generator
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
OpenAPI support has recently been added in several F# web frameworks (Oxpecker, Giraffe, Falco). However there is a problem, that F# option type is not respected well. Here is an example with Oxpecker:
```fsharp
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
open Microsoft.Extensions.DependencyInjection
open Oxpecker
open Oxpecker.OpenApi
type MyModel = { Name: string; Age: int option }
let endpoints = GET [
route "/myModel" <| %TypedResults.Ok { Name = "John"; Age = None }
|> configureEndpoint _.WithName("MyModel")
|> addOpenApiSimple
]
[]
let main args =
let builder = WebApplication.CreateBuilder(args)
builder.Services.AddRouting().AddOxpecker().AddOpenApi() |> ignore
let app = builder.Build()
app.UseRouting().UseOxpecker(endpoints) |> ignore
app.MapOpenApi() |> ignore
app.Run()
0 // Exit code
```
Generates the following schema:
```json
{
"openapi": "3.0.1",
"info": {
"title": "Empty | v1",
"version": "1.0.0"
},
"paths": {
"/myModel": {
"get": {
"tags": [
"Empty"
],
"operationId": "MyModel",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyModel"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"FSharpOptionOfint": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": "integer"
},
"MyModel": {
"required": [
"name",
"age"
],
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"$ref": "#/components/schemas/FSharpOptionOfint"
}
}
}
}
},
"tags": [
{
"name": "Empty"
}
]
}
```
### Describe the solution you'd like
I expect it to generate the same schema as with just `int`, but without making this field required:
```json
{
"openapi": "3.0.1",
"info": {
"title": "Empty | v1",
"version": "1.0.0"
},
"paths": {
"/myModel": {
"get": {
"tags": [
"Empty"
],
"operationId": "MyModel",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyModel"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"MyModel": {
"required": [
"name"
],
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "integer",
"format": "int32"
}
}
}
}
},
"tags": [
{
"name": "Empty"
}
]
}
```
### Additional context
Note that FSharp option [is already respected](https://github.com/dotnet/runtime/blob/main/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/FSharp/FSharpOptionConverter.cs) by System.Text.Json.
`ValueOption` type should also be supported in the same way.
```
.NET SDK:
Version: 9.0.101
Commit: eedb237549
Workload version: 9.0.100-manifests.4a280210
MSBuild version: 17.12.12+1cce77968
```
Contributor guide
Assessment
This issue has not been assessed yet.