[REQ] FSharp (F#) server stub based on record types
Created by: viktor-ferenczi
F#+Giraffe backend stub generator.
Alternatives attempted:
- OpenAPITypeProvider: Type provider can be used both during design time (IDE) and runtime. It generates C# classes on the fly, they are composing naturally in F#. Having to reload IDE every time changes are made to the API file. Some metadata (path, info) are also exposed. It is an excellent type provider, but we could have something more composable in F#.
- Using model classes from C# ASP.NET or NancyFX server stub: No reload issue on changes. Generates code not directly used in the F# project. It generates C# classes not composing naturally in F#.
In the above solutions classes are accessible from F# via the common platform (.NET CLI).
I suggest a new backend generating F# record types like:
type Employee =
{ name: string
; salary: float
}
Record type would provide familiar access with dot notation, plus being accessible from C# code if needed.
These generated accessors would be composable in functional code:
type Employee with
static member getName employee = employee.name
static member getSalary employee = employee.salary
static member withName value employee = {employee with name = value}
static member withSalary value employee = {employee with salary = value}
The updater has the object as its last parameter, which is good practice in functional programming.
Example usage:
let totalSalary = List.sum Employee.getSalary employees
let employeeCount = List.length employees
let equalSalary = totalSalary / (float employeeCount)
let equalEmployees = List.map (Employee.withSalary equalSalary) employees
Future versions of F# may gain new syntax for convenient property access, which will simplify the getter to: _.salary
Despite this the composable update functions (like withSalary
) will remain useful.
I suggest using the Giraffe Web framework in the generated backend stub, since it generally results in a clean default implementation. Giraffe has a SampleApp solution which could be used as the basis of the generated one.