• Stars
    star
    122
  • Rank 292,031 (Top 6 %)
  • Language
    F#
  • License
    MIT License
  • Created over 3 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

dotnet CLI tool to generate type-safe F# and Fable clients from OpenAPI/Swagger or OData services

Hawaii Nuget

A dotnet CLI tool to generate type-safe F# and Fable clients from OpenAPI/Swagger/OData services.

Features

  • Supports any OpenApi/Swagger schema in form of JSON or Yaml, compatible with those that can be read by OpenAPI.NET
  • Supports OData services (see example below), made possible by OpenAPI.NET.OData which translates the OData model into an OpenApi document
  • Generates clients for F# on dotnet or for Fable in the browser
  • Automatically handles JSON deserialization into schema types
  • Automatically handles mixed responses from end points that return binary or typed JSON responses
  • Generates discriminated union types to describe the possible responses of each endpoint
  • Generates full F# projects, including their required dependencies and targeting netstandard2.0

Install

dotnet tool install -g hawaii

Configuration

Create a configuration file called hawaii.json with the following shape:

{
    "schema": <schema>,
    "project": <project>,
    "output": <output>,
    ["target"]: <"fsharp" | "fable">
    ["synchronous"]: <true | false>,
    ["asyncReturnType"]: <"async" | "task">,
    ["resolveReferences"]: <true | false>,
    ["emptyDefinitions"]: <"ignore" | "free-form">,
    ["overrideSchema"]: <JSON schema subset>,
    ["filterTags"]: <list of tags>
}

Where

  • <schema> is a URL to the OpenApi/Swagger/OData location, whether that is an external URL or a relative file path. In case of OData services, the external URL has to end with $metadata which points to the Edm model of that service (see TripPinService example below) or it can be a local .xml file that contains the schema
  • <project> is the name of the project that will get generated
  • <output> is a relative path to the output directory where the project will be generated. (Note: this directory is deleted and re-generated when you run hawaii)
  • <synchronous> is an optional flag that determines whether hawaii should generate client methods that run http requests synchronously. This is useful when used inside console applications. (set to false by default)
  • <target> specifies whether hawaii should generate a client for F# on dotnet (default) or a Fable client
  • <asyncReturnType> is an option to determine whether hawaii should generate client methods that return Async<'T> when set to "async" (default) or Task<'T> when set to "task" (this option is irrelevant when the synchronous option is set to true)
  • <resolveReferences> determines whether hawaii will attempt to resolve external references via schema pre-processing. This is set to false by default but sometimes an OpenApi schema is scattered into multiple schemas across a repository and this might help with the resolution.
  • <emptyDefintions> determines what hawaii should do when encountering a global type definition without schema information. When set to "ignore" (default) hawaii will generate the global type. However, sometimes these global types are still referenced from other types or definitions, in which case the setting this option to "free-form" will generate a type abbreviation for the empty schema equal to a free form object (JToken when targetting F# or obj when targetting Fable)
  • <overrideSchema> Allows you to override the resolved schema either to add more information (such as a missing operation ID) or correct the types when you know better (see below)
  • <filterTags> Allows to filter which operations will be included based on their OpenAPI tags. Useful when generating the full schema isn't possible or isn't practical. To see what tags are available, use hawaii --show-tags

Example (PetStore Schema)

Here is an example configuration for the pet store API:

{
    "schema": "https://petstore3.swagger.io/api/v3/openapi.json",
    "output": "./output",
    "project": "PetStore",
    "synchronous": true
}

After you have the configuration ready, run hawaii in the directory where you have the hawaii.json file:

hawaii

You can also tell hawaii where to find the configuration file if it wasn't named hawaii.json, for example

hawaii --config ./petstore-hawaii.json

Using the generated project

Once hawaii has finished running, you find a fully generated F# project inside of the <output> directory. This project can be referenced from your application so you can start using it.

You can reference the project like this from your app like this:

<ItemGroup>
  <ProjectReference Include="..\path\to\output\PetStore.fsproj" />
</ItemGroup>

Then from your code:

open System
open System.Net.Http
open PetStore
open PetStore.Types

let petStoreUri = Uri "https://petstore3.swagger.io/api/v3"
let httpClient = new HttpClient(BaseAddress=petStoreUri)
let petStore = PetStoreClient(httpClient)

let availablePets() =
    let status = PetStatus.Available.Format()
    match petStore.findPetsByStatus(status) with
    | FindPetsByStatus.OK pets -> for pet in pets do printfn $"{pet.name}"
    | FindPetsByStatus.BadRequest -> printfn "Bad request"

availablePets()

// inventory : Map<string, int>
let (GetInventory.OK(inventory)) = petStore.getInventory()

for (status, quantity) in Map.toList inventory do
    printfn $"There are {quantity} pet(s) {status}"

Notice that you have to provide your own HttpClient to the PetStoreClient and set the BaseAddress to the base path of the service.

Example with OData (TripPinService schema)

{
  "schema": "https://services.odata.org/V4/(S(s3lb035ptje4a1j0bvkmqqa0))/TripPinServiceRW/$metadata",
  "project": "TripPinService",
  "output": "./output"
}

Generate OpenAPI specs from the OData schemas

Sometimes you want to see how Hawaii generated a client from an OData schema.

You use the following command to generate the intermediate OpenAPI specs file in the form of JSON.

Then you can inspect it but also modify then use it as your <schema> when you need to make corrections to the generated client

hawaii --from-odata-schema {schema} --output {output}

where

  • {schema} is either a URL to an external OData schema or local .xml file which the contents of the schema
  • {output} is a relative file path where the translated OpenAPI specs will be written

Example of such command

hawaii --from-odata-schema "https://services.odata.org/V4/(S(s3lb035ptje4a1j0bvkmqqa0))/TripPinServiceRW/$metadata" --output ./TripPin.json

Sample Applications

  • Minimal PetStore - A simple console application showing how to use the PetStore API client generated by Hawaii
  • Feliz PetStore - A Feliz application that shows how to use the PetStore API client generated by Hawaii when targeting Fable
  • OData TripPin Service - This application demonstrates a console application that uses a client for the TripPin OData service generated by Hawaii

Version

You can ask hawaii which version it is currently on:

hawaii --version

No Logo

If you don't want the logo to show up in your CI or local machine, add --no-logo as the last parameter

hawaii --no-logo
hawaii --config ./hawaii.json --no-logo

Advanced - Overriding The Schema

OpenAPI schemas can be very loose and not always typed. Sometimes they will be missing operation IDs on certain paths. Although Hawaii will attempt to derive valid operation IDs from the path, name collisions can sometimes happen. Hawaii provides the overrideSchema option to allow you to "fix" the source schema or add more information when its missing.

Here is an example for how you can override operation IDs for certain paths

{
  "overrideSchema": {
    "paths": {
      "/consumer/v1/services/{id}/allocations": {
        "get": {
          "operationId": "getAllocationsForCustomerByServiceId"
        }
      },
      "/consumer/v1/services/allocations/{id}": {
        "get": {
            "operationId": "getAllocationIdFromCustomerServices"
        }
      }
    }
  }
}

The overrideSchema property basically takes a subset of another schema and merges it with the source schema.

You can go a step further by overriding the return types of certain responses. The following example shows how you can get the raw text output from the default response of a path instead of getting a typed response:

{
  "overrideSchema": {
    "paths": {
      "/bin/querybuilder.json": {
        "get": {
          "responses": {
            "default": {
              "content": {
                "application/json": {
                  "schema": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Limitations

These are the very early days of Hawaii as a tool to generate F# clients and there are some known limitations and rough edges that I will be working on:

  • anyOf/oneOf not supported unless they contain a single element, in which case they are reduced away

You can watch the live coding sessions as a playlist published on YouTube here

Running integration tests

cd ./build
# run hawaii against multiple config permutations
dotnet run -- generate-and-build
# run hawaii against 10 schemas
dotnet run -- integration
# run hawaii agains the first {n} schemas out of ~2000 and see the progress
dotnet run -- rate {n}

More Repositories

1

Feliz

A fresh retake of the React API in Fable and a collection of high-quality components to build React applications in F#, optimized for happiness
F#
533
star
2

the-elmish-book

A practical guide to building modern and reliable web applications in F# from first principles
HTML
338
star
3

Npgsql.FSharp

Thin F# wrapper around Npgsql, the PostgreSQL database driver for .NET
F#
318
star
4

Fable.Remoting

Type-safe communication layer (RPC-style) for F# featuring Fable and .NET Apps
F#
273
star
5

tabula-rasa

Minimalistic real-worldish blogging platform, written entirely in F#, made as a learning reference for building large Elmish apps
F#
199
star
6

LiteDB.FSharp

Advanced F# Support for LiteDB, an embedded NoSql database for .NET with type-safe query expression through F# quotations
F#
179
star
7

Femto

Femto is a CLI tool that automatically resolves npm packages used by Fable bindings
F#
153
star
8

Snowflaqe

A dotnet CLI to generate type-safe GraphQL clients for F# and Fable with automatic deserialization, static query verification and type checking
F#
150
star
9

ThrowawayDb

Dead simple integration tests with SQL Server or Postgres throwaway databases that are created on the fly, used briefly then disposed of automagically.
C#
140
star
10

Npgsql.FSharp.Analyzer

F# analyzer that provides embedded SQL syntax analysis, type-checking for parameters and result sets and nullable column detection when writing queries using Npgsql.FSharp.
C#
132
star
11

SAFE.Simplified

A lightweight alternative template of SAFE for happy cross-IDE full-stack F# development
F#
101
star
12

Fable.SimpleHttp

Http with Fable, made simple.
F#
82
star
13

ClosedXML.SimpleSheets

Easily generate Excel sheets from F#
F#
80
star
14

DustyTables

Thin F# API for SqlClient for easy data access to ms sql server with functional seasoning on top
F#
74
star
15

Giraffe.GoodRead

Practical dependency injection in Giraffe that gets out of your way
F#
73
star
16

Feliz.Router

A router component for React and Elmish that is focused, powerful and extremely easy to use.
F#
72
star
17

Fable.SimpleJson

A library for working with JSON in Fable projects
F#
56
star
18

SAFE.React

Full Stack F# powered by ASP.NET Core on the backend and modern React on the frontend.
F#
54
star
19

Fable.Mocha

Fable library for a proper testing story using different runners such as mocha, standalone browsers and dotnet
F#
51
star
20

fabulous-simple-elements

An alternative view rendering API for Fabulous (Elmish Xamarin.Forms) that is easy to use and simple to read, inspired by Elmish on the web.
F#
46
star
21

desktop-feliz-with-photino

F#
43
star
22

fsharp-weekly

F# Weekly mobile, available for Android (soon iOS and UWP too)
F#
42
star
23

SAFE-TodoList

The simplest Todo app showcasing a client-server application written entirely in F#
F#
41
star
24

Giraffe.SerilogExtensions

Dead simple library to integrate Serilog within Giraffe apps: implemented as a composable HttpHandler and has native destructuring of F# types.
F#
30
star
25

dotnetconf-react-with-fsharp

Demo application used in DotnetCONF to build React applications with F#
F#
30
star
26

Elmish.SweetAlert

SweetAlert integration for Fable, made with ❀️ to work in Elmish apps. https://zaid-ajaj.github.io/Elmish.SweetAlert/
F#
29
star
27

Fable.DateFunctions

Fable binding for date-fns javascript library, implemented as extension methods for DateTime. See https://zaid-ajaj.github.io/Fable.DateFunctions/
F#
27
star
28

Fable.CloudFlareWorkers

Write CloudFlare Workers in idiomatic, type-safe F# and compile them to JS using Fable
F#
24
star
29

Elmish.Toastr

Toastr integration with Fable, implemented as Elmish commands https://zaid-ajaj.github.io/Elmish.Toastr/
F#
24
star
30

elmish-getting-started

A simple and minimalistic template to easily get up and running with Elmish and Fable
F#
22
star
31

Giraffe.QueryReader

HttpHandler for easily working with query string parameters within Giraffe apps.
F#
21
star
32

navigation-bar-with-feliz

Modern navigation bar built with Feliz
JavaScript
20
star
33

fable-getting-started

Template for getting started with Fable
JavaScript
19
star
34

Giraffe.JsonTherapy

Simply extract JSON values from HTTP requests without defining intermediate types or using model binding
F#
19
star
35

Feliz.ViewEngine.Htmx

A library that allows using Htmx attributes with Feliz.ViewEngine
F#
18
star
36

Fable.SimpleXml

A library for easily parsing and working with XML in Fable projects
F#
17
star
37

AlgebraFs

A simple computer algebra system (CAS), written in F# for fun and learning.
F#
15
star
38

Fable.React.Flatpickr

Fable binding for react-flatpickr that is ready to use within Elmish applications
F#
14
star
39

elmish-login-flow-validation

Elmish sample that demonstrates a login flow with user input validation
F#
13
star
40

pulumi-schema-explorer

Web application and UI to explore Pulumi schemas
F#
13
star
41

Fable.SqlClient

Fable Node client for Microsoft SQL Server, built around a node-mssql binding
F#
12
star
42

pulumi-csharp-analyzer

Roslyn-based static code analysis for pulumi programs written in C#
C#
11
star
43

Elmish.AnimatedTree

An animated tree user interface made for Elmish applications
JavaScript
11
star
44

elmish-composition

A library to compare the different compositional techniques in Elmish applications
JavaScript
10
star
45

Cable

Type-safe client-server communication for C# featuring Bridge.NET and NancyFx
C#
10
star
46

Nancy.Serilog

Nancy plugin for application-wide logging using Serilog
C#
9
star
47

scaling-elmish-programs

FableConf 2018 slides and apps used in the presentation
F#
8
star
48

Suave.SerilogExtensions

Suave plugin to use the awesome Serilog library as the logger for your application
F#
8
star
49

ElmCounterWPF

Pure F#/Xaml counter using Elmish.WPF and XAML type provider
F#
7
star
50

ReactCSharpDemo

Using React in C# with Bridge
C#
7
star
51

Feliz.AntDesign

AntDesign bindings using Feliz syntax for a clean, discoverable and type-safe React components. (WIP)
F#
7
star
52

Fable.SimpleJson.Python

A library for working with JSON in F# Fable projects targeting Python
F#
7
star
53

hawaii-samples-feliz-petstore

This is a sample application that shows how to use Feliz with a client generated by Hawaii
F#
6
star
54

elmish-wpf-template

A template for easily getting started with building WPF apps using Elmish
F#
5
star
55

elmish-routing

F#
4
star
56

Bridge.Redux

Bindings of the Redux library for the Bridge transpiler
C#
4
star
57

Fable.Requests

Fable library for making HTTP requests targeting Python
F#
4
star
58

elmish-todo-exercises

F#
4
star
59

ExcelPluginTemplate

Template project to create Excel Add-ins with F# and ExcelDNA
F#
3
star
60

elmish-calc

Calculator application with Fable and Fable-Elmish
F#
3
star
61

interop-fableconf2019

JavaScript
3
star
62

FifteenPuzzleWithFeliz

The small fifteen puzzle game I am building live on Twitch
JavaScript
3
star
63

FSharp.SimpleJson

A library for easily parsing, transforming and converting JSON in F#, ported from Fable.SimpleJson
F#
3
star
64

docute-starter

a simple and easy to use project to start writing documentation with Docute
HTML
3
star
65

Bridge.ChartJS

Bindings for Chart.js library to be used in Bridge.NET projects
C#
3
star
66

Bridge.CanvasJS

CanvasJS C#-wrapper for Bridge.NET project.
C#
3
star
67

pulumi-workshop-automation-fsharp

This workshop will walk you through the basics of using the Automation API of Pulumi to create and deploy a Pulumi stack programmatically with F#
F#
3
star
68

MandelbrotHaskell

Mandelbrot fractal as text (ASCII), written in Haskell
Haskell
2
star
69

hawaii-samples-petstore

PetStore API sample with Hawaii
F#
2
star
70

fsharp-exchange-2021

Code repository for the F# eXchange 2021 conference
F#
2
star
71

terraform-basic-vpc-to-pulumi

HCL
2
star
72

Cable.ArticleSample

Type-safe web app sample used to demonstrate Cable
C#
2
star
73

SAFE-FileUploadDownload

F#
2
star
74

login-with-url-extended

F#
2
star
75

hawaii-samples-odata-trippin

F#
2
star
76

ReactReduxTodoApp

Todo app written in pure C# with React and Redux
C#
2
star
77

Simple-Feliz-i18n

Using Feliz template, this repository shows how to implement a simple internationalization mechanism that makes parts of the application be dependent on the current users' locale.
JavaScript
2
star
78

Fable.React.Responsive

Fable binding for react-responsive that is ready to use within Elmish applications
F#
1
star
79

remoting-pure-kestrel

The simplest AspNetCore sample with Fable.Remoting using the Kestrel server
F#
1
star
80

Bridge.SweetAlert

SweetAlert bindings for the Bridge.NET project.
CSS
1
star
81

Image-Processor

A program to process and filter images, written in C#.
C#
1
star
82

FableSuaveSample

Fable and Suave sample for integration-testing Fable.Remoting with Suave to the death
F#
1
star
83

ChristianHolidaysAssignment

C++
1
star
84

gitbook-enhanced-katex

Math typesetting using KaTex for gitBook
JavaScript
1
star
85

RemotingJsonBenchmarks

F#
1
star
86

pulumi-codegen-dotnet

Building Pulumi Codegen tooling in F#
F#
1
star
87

elmish-todo-part1

F#
1
star
88

WindowsExplorer

A WPF application that mimics Windows Explorer functionality
C#
1
star
89

elmish-hackernews-part1

F#
1
star
90

elmish-todo-part2

F#
1
star
91

fast-refresh-bug-reproduction

JavaScript
1
star
92

tagmeme-analyzer

Static code analyzer that checks for exhaustive pattern matching, union case typos and redundant arguments in tagmeme
JavaScript
1
star
93

xmlhttprequest-in-elmish

F#
1
star
94

Bridge.Ractive

Bindings of Ractive.js to be used in Bridge.NET projects.
JavaScript
1
star
95

elmish-hackernews-part3

F#
1
star
96

elmish-todo-part3

F#
1
star