https://github.com/badsyntax/openapi-dotnet-react-typescript-fetch-example
An example project showing how to use the OpenAPI typescript-fetch HTTP client with React
https://github.com/badsyntax/openapi-dotnet-react-typescript-fetch-example
openapi openapi-generator react react-query swagger typescript
Last synced: 10 months ago
JSON representation
An example project showing how to use the OpenAPI typescript-fetch HTTP client with React
- Host: GitHub
- URL: https://github.com/badsyntax/openapi-dotnet-react-typescript-fetch-example
- Owner: badsyntax
- Created: 2021-08-27T05:57:03.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-10-17T05:32:35.000Z (about 4 years ago)
- Last Synced: 2025-02-28T22:55:08.110Z (10 months ago)
- Topics: openapi, openapi-generator, react, react-query, swagger, typescript
- Language: Mustache
- Homepage: https://richardwillis.info/blog/generate-a-type-script-http-client-from-an-open-api-spec-in-dot-net-5
- Size: 436 KB
- Stars: 5
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# openapi-dotnet-react-typescript-fetch-example
An example project that demonstrates how to:
- Generate a typed HTTP client package from an OpenAPI definition using the [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator) [`typescript-fetch`](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/typescript-fetch.md) template
- Consume the HTTP client in a React application using [react-query](https://github.com/tannerlinsley/react-query)
## Project Overview
```console
├── HTTPClient/lib # The generated typescript-fetch HTTP client
├── ReactApp # A TypeScript React front-end application that consumes the HTTP Client
├── WebAPI # A .NET 5 web API that provides the OpenAPI definitions
```
### Generating the HTTP Client
The following software is required:
- [.NET 5.0](https://dotnet.microsoft.com/download/dotnet/5.0)
- [Node.js 16](https://nodejs.org/)
Run the folllowing to generate the client:
```console
dotnet tool restore
dotnet msbuild -target:GenerateHTTPClient WebAPI -property:Configuration=Release
```
The [build script](https://github.com/badsyntax/openapi-typescript-fetch-example/blob/1bc5fa198157f08ba4fe4cc61b276bc39d135dde/WebAPI/WebAPI.csproj#L12-L16) does the following:
- Builds the WebAPI .NET application
- Extracts the OpenAPI spec from the .NET application to location `./HTTPClient/api-spec.json`
- Runs some `npm scripts` within `./HTTPClient` to generate the client (Refer to the scripts in [`./HTTPClient/package.json`](./HTTPClient/package.json))
## Consuming the HTTP Client with React
### API Setup
API instances and react-query are setup within [./ReactApp/src/api](./ReactApp/src/api), for example:
```ts
import {
Configuration,
ConfigurationParameters,
WeatherForecastApi,
} from 'example-service-client';
import { ApiMiddleware } from './ApiMiddleware';
const configParams: ConfigurationParameters = {
basePath: 'https://localhost:5001',
middleware: [new ApiMiddleware()],
};
const apiConfig = new Configuration(configParams);
export const apiClient = {
weatherForecastApi: new WeatherForecastApi(apiConfig),
};
export type ApiClient = typeof apiClient;
```
### Query Hooks
[Query hooks](./ReactApp/src/api/hooks/) call the generated HTTP Client methods, and support request cancellation, for example:
```ts
import { WeatherForecast } from 'example-service-client';
import { useQuery, UseQueryOptions, UseQueryResult } from 'react-query';
import { ResponseError } from '../types';
import { withQueryCancellation } from '../util/withQueryCancellation';
import { useApiClient } from './useApiClient';
export const getWeatherForecastKey = 'getWeatherForecast';
export function useGetWeatherForecast(
options?: UseQueryOptions, ResponseError>
): UseQueryResult, ResponseError> {
const { weatherForecastApi } = useApiClient();
return useQuery(
getWeatherForecastKey,
withQueryCancellation((signal) =>
weatherForecastApi.weatherForecastGet({ signal })
),
options
);
}
```
Query hooks are called in [React components](./ReactApp/src/App/App.tsx), for example:
```tsx
export const App: React.FC = () => {
const queryClient = useQueryClient();
const {
data = [],
error,
isFetching,
refetch,
} = useGetWeatherForecast({
enabled: false,
});
const getWeatherForecast = () => {
if (!isFetching) {
refetch();
}
};
const cancelGetWeatherForecast = () => {
void queryClient.cancelQueries(getWeatherForecastKey);
};
return (
Get Weather Forecast
{isFetching && (
Loading...(
Cancel
)
)}
{error && Error! {getResponseErrorMessage(error)}
}
{data.map((forecast, i) => (
{forecast.summary} ({forecast.temperatureC}C)
))}
);
};
```
## Running the WebAPI
```console
dotnet run --project WebAPI
```
Swagger is then available at:
## Running the React App
```console
npm start --prefix ReactApp
```
## How this project was bootstrapped
```console
dotnet new gitignore
dotnet new tool-manifest
dotnet new nugetconfig
dotnet tool install Swashbuckle.AspNetCore.Cli
dotnet new sln --name OpenAPITypeScriptFetchExample
dotnet new webapi -o WebAPI
dotnet sln add WebAPI
# .editorconfig config manually created from https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options
npx create-react-app react-app --template typescript
mv react-app ReactApp
```
## TODO
- [ ] Add bearer token auth to .NET project