diff --git a/docs/src/content/docs/openapi-fetch/examples.md b/docs/src/content/docs/openapi-fetch/examples.md index 8ced98832..7908eb939 100644 --- a/docs/src/content/docs/openapi-fetch/examples.md +++ b/docs/src/content/docs/openapi-fetch/examples.md @@ -78,9 +78,11 @@ openapi-fetch is simple vanilla JS that can be used in any project. But sometime [View a code example in GitHub](https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch/examples/react-query) -### React + SWR +### Next.js -TODO +Next.js is the most popular SSR framework for React. While [React Query](#react--react-query) is recommended for clientside fetching, this example shows how to take advantage of server-side fetching. + +[View a code example in GitHub](https://github.com/drwpow/openapi-typescript/tree/main/packages/openapi-fetch/examples/nextjs) ### Svelte / SvelteKit diff --git a/packages/openapi-fetch/examples/nextjs/.gitignore b/packages/openapi-fetch/examples/nextjs/.gitignore new file mode 100644 index 000000000..8f322f0d8 --- /dev/null +++ b/packages/openapi-fetch/examples/nextjs/.gitignore @@ -0,0 +1,35 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/packages/openapi-fetch/examples/nextjs/README.md b/packages/openapi-fetch/examples/nextjs/README.md new file mode 100644 index 000000000..4c9bed7ba --- /dev/null +++ b/packages/openapi-fetch/examples/nextjs/README.md @@ -0,0 +1,14 @@ +# openapi-fetch + Next.js + +Example of using openapi-fetch in [Next.js](https://nextjs.org) using server-rendered data. + +For an example of fetching clientside, see the [React Query example](../react-query) which also works in Next.js (React Query is recommended over SWR because of type inference). + +## Setup + +```sh +pnpm i +pnpm run dev +``` + +You’ll see the server running at `localhost:3000` diff --git a/packages/openapi-fetch/examples/nextjs/app/favicon.ico b/packages/openapi-fetch/examples/nextjs/app/favicon.ico new file mode 100644 index 000000000..718d6fea4 Binary files /dev/null and b/packages/openapi-fetch/examples/nextjs/app/favicon.ico differ diff --git a/packages/openapi-fetch/examples/nextjs/app/layout.tsx b/packages/openapi-fetch/examples/nextjs/app/layout.tsx new file mode 100644 index 000000000..33d46c728 --- /dev/null +++ b/packages/openapi-fetch/examples/nextjs/app/layout.tsx @@ -0,0 +1,13 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "openapi-fetch + Next.js", +}; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + +
{children} + + ); +} diff --git a/packages/openapi-fetch/examples/nextjs/app/page.tsx b/packages/openapi-fetch/examples/nextjs/app/page.tsx new file mode 100644 index 000000000..5afc1b31b --- /dev/null +++ b/packages/openapi-fetch/examples/nextjs/app/page.tsx @@ -0,0 +1,25 @@ +import client from "../lib/api"; + +async function getFact() { + return await client.GET("/fact", { + params: { + query: { max_length: 500 }, + }, + }); +} + +export default async function Home() { + const fact = await getFact(); + + return ( +
+ {JSON.stringify(fact.data, undefined, 2)}
+
+ )}
+
{JSON.stringify(fact.data, undefined, 2)}
diff --git a/packages/openapi-fetch/examples/react-query/src/lib/api/v1.d.ts b/packages/openapi-fetch/examples/react-query/src/lib/api/v1.d.ts
index 335091dfa..fad1c0cc0 100644
--- a/packages/openapi-fetch/examples/react-query/src/lib/api/v1.d.ts
+++ b/packages/openapi-fetch/examples/react-query/src/lib/api/v1.d.ts
@@ -86,6 +86,10 @@ export interface components {
*/
length?: number;
};
+ Error: {
+ code: number;
+ message: string;
+ };
};
responses: never;
parameters: never;
@@ -116,6 +120,12 @@ export interface operations {
"application/json": components["schemas"]["Breed"][];
};
};
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
};
};
/**
@@ -136,9 +146,17 @@ export interface operations {
"application/json": components["schemas"]["CatFact"];
};
};
- /** @description Fact not found */
+ /** @description not found */
404: {
- content: never;
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
};
};
};
@@ -162,6 +180,12 @@ export interface operations {
"application/json": components["schemas"]["CatFact"][];
};
};
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
};
};
}
diff --git a/packages/openapi-fetch/examples/react-query/src/lib/api/v1.json b/packages/openapi-fetch/examples/react-query/src/lib/api/v1.json
index 198b17f79..baf0c069e 100644
--- a/packages/openapi-fetch/examples/react-query/src/lib/api/v1.json
+++ b/packages/openapi-fetch/examples/react-query/src/lib/api/v1.json
@@ -36,6 +36,16 @@
}
}
}
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -70,7 +80,24 @@
}
},
"404": {
- "description": "Fact not found"
+ "description": "not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -116,6 +143,16 @@
}
}
}
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -178,6 +215,14 @@
}
},
"type": "object"
+ },
+ "Error": {
+ "type": "object",
+ "required": ["code", "message"],
+ "properties": {
+ "code": { "type": "number" },
+ "message": { "type": "string" }
+ }
}
}
}
diff --git a/packages/openapi-fetch/examples/sveltekit/package.json b/packages/openapi-fetch/examples/sveltekit/package.json
index db5df1404..e7a0415e6 100644
--- a/packages/openapi-fetch/examples/sveltekit/package.json
+++ b/packages/openapi-fetch/examples/sveltekit/package.json
@@ -1,7 +1,7 @@
{
- "name": "sveltekit",
- "version": "0.0.1",
+ "name": "@example/openapi-fetch-sveltekit",
"private": true,
+ "type": "module",
"scripts": {
"dev": "vite dev",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
@@ -20,6 +20,5 @@
"tslib": "^2.6.2",
"typescript": "^5.1.6",
"vite": "^4.4.9"
- },
- "type": "module"
+ }
}
diff --git a/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.d.ts b/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.d.ts
index 335091dfa..fad1c0cc0 100644
--- a/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.d.ts
+++ b/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.d.ts
@@ -86,6 +86,10 @@ export interface components {
*/
length?: number;
};
+ Error: {
+ code: number;
+ message: string;
+ };
};
responses: never;
parameters: never;
@@ -116,6 +120,12 @@ export interface operations {
"application/json": components["schemas"]["Breed"][];
};
};
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
};
};
/**
@@ -136,9 +146,17 @@ export interface operations {
"application/json": components["schemas"]["CatFact"];
};
};
- /** @description Fact not found */
+ /** @description not found */
404: {
- content: never;
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
};
};
};
@@ -162,6 +180,12 @@ export interface operations {
"application/json": components["schemas"]["CatFact"][];
};
};
+ /** @description error */
+ default: {
+ content: {
+ "application/json": components["schemas"]["Error"];
+ };
+ };
};
};
}
diff --git a/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.json b/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.json
index 198b17f79..baf0c069e 100644
--- a/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.json
+++ b/packages/openapi-fetch/examples/sveltekit/src/lib/api/v1.json
@@ -36,6 +36,16 @@
}
}
}
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -70,7 +80,24 @@
}
},
"404": {
- "description": "Fact not found"
+ "description": "not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -116,6 +143,16 @@
}
}
}
+ },
+ "default": {
+ "description": "error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ }
+ }
+ }
}
}
}
@@ -178,6 +215,14 @@
}
},
"type": "object"
+ },
+ "Error": {
+ "type": "object",
+ "required": ["code", "message"],
+ "properties": {
+ "code": { "type": "number" },
+ "message": { "type": "string" }
+ }
}
}
}
diff --git a/packages/openapi-fetch/examples/sveltekit/src/routes/+page.svelte b/packages/openapi-fetch/examples/sveltekit/src/routes/+page.svelte
index b3cfa1234..ccd8001b3 100644
--- a/packages/openapi-fetch/examples/sveltekit/src/routes/+page.svelte
+++ b/packages/openapi-fetch/examples/sveltekit/src/routes/+page.svelte
@@ -1,23 +1,30 @@
Example: Client | Page Data
- {#await fact} -{JSON.stringify(data, undefined, 2)}
+ {JSON.stringify(fact.data, undefined, 2)}
{/if}
- {/await}
-
+ {/if}
+
Example: Client | Page Data
{#if data.fact.error} -{JSON.stringify(data.fact.data, undefined, 2)}
{:else}