{"id":13779146,"url":"https://github.com/Zaid-Ajaj/Hawaii","last_synced_at":"2025-05-11T12:32:53.687Z","repository":{"id":43013197,"uuid":"361887976","full_name":"Zaid-Ajaj/Hawaii","owner":"Zaid-Ajaj","description":"dotnet CLI tool to generate type-safe F# and Fable clients from OpenAPI/Swagger or OData  services","archived":false,"fork":false,"pushed_at":"2024-04-08T13:02:00.000Z","size":936,"stargazers_count":141,"open_issues_count":8,"forks_count":15,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-03T00:10:10.502Z","etag":null,"topics":["dotnet-cli","fsharp","openapi","openapi-documents","openapi-generator","swagger"],"latest_commit_sha":null,"homepage":"","language":"F#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Zaid-Ajaj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-26T20:39:56.000Z","updated_at":"2024-10-18T07:47:09.000Z","dependencies_parsed_at":"2024-04-08T14:04:50.924Z","dependency_job_id":null,"html_url":"https://github.com/Zaid-Ajaj/Hawaii","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zaid-Ajaj%2FHawaii","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zaid-Ajaj%2FHawaii/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zaid-Ajaj%2FHawaii/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Zaid-Ajaj%2FHawaii/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Zaid-Ajaj","download_url":"https://codeload.github.com/Zaid-Ajaj/Hawaii/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225049029,"owners_count":17412912,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet-cli","fsharp","openapi","openapi-documents","openapi-generator","swagger"],"created_at":"2024-08-03T18:01:01.719Z","updated_at":"2024-11-17T14:31:12.974Z","avatar_url":"https://github.com/Zaid-Ajaj.png","language":"F#","funding_links":[],"categories":["Code Generation"],"sub_categories":[],"readme":"# Hawaii  [![Nuget](https://img.shields.io/nuget/v/Hawaii.svg?colorB=green)](https://www.nuget.org/packages/Hawaii)\n\n![](hawaii.png)\n\nA dotnet CLI tool to generate type-safe F# and Fable clients from OpenAPI/Swagger/OData services.\n\n### Features\n - Supports any OpenApi/Swagger schema in form of JSON or Yaml, compatible with those that can be read by [OpenAPI.NET](https://github.com/microsoft/OpenAPI.NET)\n - Supports [OData](https://www.odata.org) services (see example below), made possible by [OpenAPI.NET.OData](https://github.com/Microsoft/OpenAPI.NET.OData) which translates the OData model into an OpenApi document\n - Generates clients for F# on dotnet or for Fable in the browser\n - Automatically handles JSON deserialization into schema types\n - Automatically handles mixed responses from end points that return binary _or_ typed JSON responses\n - Generates discriminated union types to describe the possible responses of each endpoint\n - Generates full F# projects, including their required dependencies and targeting `netstandard2.0`\n\n### Install\n\n```\ndotnet tool install -g hawaii\n```\n\n### Configuration\n\nCreate a configuration file called `hawaii.json` with the following shape:\n```\n{\n    \"schema\": \u003cschema\u003e,\n    \"project\": \u003cproject\u003e,\n    \"output\": \u003coutput\u003e,\n    [\"target\"]: \u003c\"fsharp\" | \"fable\"\u003e\n    [\"synchronous\"]: \u003ctrue | false\u003e,\n    [\"asyncReturnType\"]: \u003c\"async\" | \"task\"\u003e,\n    [\"resolveReferences\"]: \u003ctrue | false\u003e,\n    [\"emptyDefinitions\"]: \u003c\"ignore\" | \"free-form\"\u003e,\n    [\"overrideSchema\"]: \u003cJSON schema subset\u003e,\n    [\"filterTags\"]: \u003clist of tags\u003e\n}\n```\nWhere\n - `\u003cschema\u003e` 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\n - `\u003cproject\u003e` is the name of the project that will get generated\n - `\u003coutput\u003e` 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`)\n - `\u003csynchronous\u003e` 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)\n - `\u003ctarget\u003e` specifies whether hawaii should generate a client for F# on dotnet  (default) or a Fable client\n - `\u003casyncReturnType\u003e` is an option to determine whether hawaii should generate client methods that return `Async\u003c'T\u003e` when set to \"async\" (default) or `Task\u003c'T\u003e` when set to \"task\" (this option is irrelevant when the `synchronous` option is set to `true`)\n - `\u003cresolveReferences\u003e` 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.\n - `\u003cemptyDefintions\u003e` 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)\n - `\u003coverrideSchema\u003e` 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)\n - `\u003cfilterTags\u003e` 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`\n\n### Example ([PetStore](https://petstore3.swagger.io) Schema)\nHere is an example configuration for the pet store API:\n```json\n{\n    \"schema\": \"https://petstore3.swagger.io/api/v3/openapi.json\",\n    \"output\": \"./output\",\n    \"project\": \"PetStore\",\n    \"synchronous\": true\n}\n```\nAfter you have the configuration ready, run `hawaii` in the directory where you have the `hawaii.json` file:\n```\nhawaii\n```\nYou can also tell hawaii where to find the configuration file if it wasn't named `hawaii.json`, for example\n```\nhawaii --config ./petstore-hawaii.json\n```\n### Using the generated project\nOnce hawaii has finished running, you find a fully generated F# project inside of the `\u003coutput\u003e` directory. This project can be referenced from your application so you can start using it.\n\nYou can reference the project like this from your app like this:\n```xml\n\u003cItemGroup\u003e\n  \u003cProjectReference Include=\"..\\path\\to\\output\\PetStore.fsproj\" /\u003e\n\u003c/ItemGroup\u003e\n```\nThen from your code:\n```fs\nopen System\nopen System.Net.Http\nopen PetStore\nopen PetStore.Types\n\nlet petStoreUri = Uri \"https://petstore3.swagger.io/api/v3\"\nlet httpClient = new HttpClient(BaseAddress=petStoreUri)\nlet petStore = PetStoreClient(httpClient)\n\nlet availablePets() =\n    let status = PetStatus.Available.Format()\n    match petStore.findPetsByStatus(status) with\n    | FindPetsByStatus.OK pets -\u003e for pet in pets do printfn $\"{pet.name}\"\n    | FindPetsByStatus.BadRequest -\u003e printfn \"Bad request\"\n\navailablePets()\n\n// inventory : Map\u003cstring, int\u003e\nlet (GetInventory.OK(inventory)) = petStore.getInventory()\n\nfor (status, quantity) in Map.toList inventory do\n    printfn $\"There are {quantity} pet(s) {status}\"\n```\nNotice that you have to provide your own `HttpClient` to the `PetStoreClient` and set the `BaseAddress` to the base path of the service.\n\n### Example with OData ([TripPinService](https://services.odata.org/v4/TripPinServiceRW) schema)\n```json\n{\n  \"schema\": \"https://services.odata.org/V4/(S(s3lb035ptje4a1j0bvkmqqa0))/TripPinServiceRW/$metadata\",\n  \"project\": \"TripPinService\",\n  \"output\": \"./output\"\n}\n```\n\n### Generate OpenAPI specs from the OData schemas\n\nSometimes you want to see how Hawaii generated a client from an OData schema. \n\nYou use the following command to generate the intermediate OpenAPI specs file in the form of JSON.\n\nThen you can inspect it but also modify then use it as your `\u003cschema\u003e` when you need to make corrections to the generated client\n\n```\nhawaii --from-odata-schema {schema} --output {output}\n```\nwhere\n  - `{schema}` is either a URL to an external OData schema or local .xml file which the contents of the schema\n  - `{output}` is a relative file path where the translated OpenAPI specs will be written\n\nExample of such command\n```\nhawaii --from-odata-schema \"https://services.odata.org/V4/(S(s3lb035ptje4a1j0bvkmqqa0))/TripPinServiceRW/$metadata\" --output ./TripPin.json\n```\n### Sample Applications\n\n- [Minimal PetStore](https://github.com/Zaid-Ajaj/hawaii-samples-petstore) - A simple console application showing how to use the PetStore API client generated by Hawaii\n- [Feliz PetStore](https://github.com/Zaid-Ajaj/hawaii-samples-feliz-petstore) - A [Feliz](https://github.com/Zaid-Ajaj/Feliz) application that shows how to use the PetStore API client generated by Hawaii when targeting Fable\n- [OData TripPin Service](https://github.com/Zaid-Ajaj/hawaii-samples-odata-trippin) - This application demonstrates a console application that uses a client for the [TripPin](https://www.odata.org/blog/trippin-new-odata-v4-sample-service) OData service generated by [Hawaii](https://github.com/Zaid-Ajaj/Hawaii)\n\n### Version\nYou can ask hawaii which version it is currently on:\n```\nhawaii --version\n```\n\n### No Logo\nIf you don't want the logo to show up in your CI or local machine, add `--no-logo` as the last parameter\n```\nhawaii --no-logo\nhawaii --config ./hawaii.json --no-logo\n```\n\n### Advanced - Overriding The Schema\nOpenAPI 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.\nHawaii provides the `overrideSchema` option to allow you to \"fix\" the source schema or add more information when its missing.\n\nHere is an example for how you can override operation IDs for certain paths\n```json\n{\n  \"overrideSchema\": {\n    \"paths\": {\n      \"/consumer/v1/services/{id}/allocations\": {\n        \"get\": {\n          \"operationId\": \"getAllocationsForCustomerByServiceId\"\n        }\n      },\n      \"/consumer/v1/services/allocations/{id}\": {\n        \"get\": {\n            \"operationId\": \"getAllocationIdFromCustomerServices\"\n        }\n      }\n    }\n  }\n}\n```\nThe `overrideSchema` property basically takes a subset of another schema and _merges_ it with the source schema.\n\nYou 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:\n```json\n{\n  \"overrideSchema\": {\n    \"paths\": {\n      \"/bin/querybuilder.json\": {\n        \"get\": {\n          \"responses\": {\n            \"default\": {\n              \"content\": {\n                \"application/json\": {\n                  \"schema\": {\n                    \"type\": \"string\"\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Limitations\nThese 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:\n - `anyOf`/`oneOf` not supported unless they contain a single element, in which case they are reduced away\n\n\u003e You can watch the live coding sessions as a playlist published on [YouTube here](https://www.youtube.com/watch?v=8dgjD6vG7yw\u0026list=PLBzGkJMamtz0KCkK7OFnuXyXP7yUtnt9o)\n\n### Running integration tests\n```bash\ncd ./build\n# run hawaii against multiple config permutations\ndotnet run -- generate-and-build\n# run hawaii against 10 schemas\ndotnet run -- integration\n# run hawaii agains the first {n} schemas out of ~2000 and see the progress\ndotnet run -- rate {n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZaid-Ajaj%2FHawaii","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FZaid-Ajaj%2FHawaii","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FZaid-Ajaj%2FHawaii/lists"}