-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from junjie-w/develop
Merge Develop into Main
- Loading branch information
Showing
37 changed files
with
2,779 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,73 +1,110 @@ | ||
# Turborepo Design System starter with Changesets | ||
|
||
This is an official React design system starter powered by Turborepo. Versioning and package publishing is handled by [Changesets](https://github.com/changesets/changesets) and fully automated with GitHub Actions. | ||
|
||
## Using this example | ||
|
||
Run the following command: | ||
|
||
```sh | ||
npx create-turbo@latest -e with-changesets | ||
# API Client SDK Streamline Sample | ||
|
||
A demonstration of streamlined API client SDK development, from API specification to client usage. | ||
|
||
## Project Flow | ||
|
||
1. API Development | ||
2. Push Spec to SwaggerHub | ||
3. Publish SDK to NPM | ||
4. Use API Client Config in API Routes | ||
|
||
## Project Structure | ||
|
||
- Root | ||
- apps | ||
- ecom-app | ||
- api (Route Handlers) | ||
- lib (API Client Config) | ||
- products-api | ||
- users-api | ||
- packages | ||
- openapi-fetch-runtime | ||
- workflows (GitHub Actions) | ||
|
||
## Features | ||
|
||
- 🔄 Automated API spec publishing | ||
- 📦 Streamlined SDK generation | ||
- 🛠 Centralized client configuration | ||
- 🌟 Type-safe API interactions | ||
|
||
## How It Works | ||
|
||
### 1. API Development | ||
- NestJS APIs with OpenAPI decorators | ||
- Automated spec generation | ||
- GitHub Actions workflow for spec publishing | ||
|
||
### 2. SDK Generation | ||
- OpenAPI Generator with customized templates | ||
- Automated NPM package publishing | ||
- Runtime package for shared utilities | ||
|
||
### 3. Client Configuration | ||
- Environment-based configuration | ||
- Error handling and logging | ||
- Client instance caching | ||
- Request middleware | ||
|
||
### 4. API Routes | ||
- Type-safe API client usage | ||
- Proxy route implementations | ||
- Error handling and response mapping | ||
|
||
## Usage | ||
|
||
1. Push API Spec: | ||
```bash | ||
# Triggered via GitHub Actions | ||
- GitHub workflow publishes spec | ||
``` | ||
|
||
## What's inside? | ||
|
||
This Turborepo includes the following: | ||
|
||
### Apps and Packages | ||
|
||
- `docs`: A placeholder documentation site powered by [Next.js](https://nextjs.org/) | ||
- `@acme/core`: core React components | ||
- `@acme/utils`: shared React utilities | ||
- `@acme/tsconfig`: shared `tsconfig.json`s used throughout the monorepo | ||
- `@acme/eslint-config`: ESLint preset | ||
|
||
Each package and app is 100% [TypeScript](https://www.typescriptlang.org/). | ||
|
||
### Utilities | ||
|
||
This Turborepo has some additional tools already setup for you: | ||
|
||
- [TypeScript](https://www.typescriptlang.org/) for static type checking | ||
- [ESLint](https://eslint.org/) for code linting | ||
- [Prettier](https://prettier.io) for code formatting | ||
|
||
### Useful commands | ||
|
||
- `yarn build` - Build all packages and the docs site | ||
- `yarn dev` - Develop all packages and the docs site | ||
- `yarn lint` - Lint all packages | ||
- `yarn changeset` - Generate a changeset | ||
- `yarn clean` - Clean up all `node_modules` and `dist` folders (runs each package's clean script) | ||
|
||
### Changing the npm organization scope | ||
|
||
The npm organization scope for this design system starter is `@acme`. To change this, it's a bit manual at the moment, but you'll need to do the following: | ||
2. Generate SDK: | ||
```bash | ||
# Automated via GitHub Actions | ||
- Pull spec from SwaggerHub | ||
- Generate TypeScript client | ||
- Publish to NPM | ||
``` | ||
|
||
- Rename folders in `packages/*` to replace `acme` with your desired scope | ||
- Search and replace `acme` with your desired scope | ||
- Re-run `yarn install` | ||
3. Use in Routes: | ||
```typescript | ||
import { getProductsApi } from '@/lib/api-client-config' | ||
|
||
## Versioning and Publishing packages | ||
export async function GET() { | ||
const productsApi = getProductsApi() | ||
const products = await productsApi.findAll() | ||
return NextResponse.json(products) | ||
} | ||
``` | ||
|
||
Package publishing has been configured using [Changesets](https://github.com/changesets/changesets). Please review their [documentation](https://github.com/changesets/changesets#documentation) to familiarize yourself with the workflow. | ||
## Links | ||
|
||
This example comes with automated npm releases setup in a [GitHub Action](https://github.com/changesets/action). To get this working, you will need to create an `NPM_TOKEN` and `GITHUB_TOKEN` in your repository settings. You should also install the [Changesets bot](https://github.com/apps/changeset-bot) on your GitHub repository as well. | ||
- [Products API Spec](https://app.swaggerhub.com/apis/junjie.wu/sample-products-api) | ||
- [Users API Spec](https://app.swaggerhub.com/apis/junjie.wu/sample-users-api) | ||
- [Products SDK Package](https://www.npmjs.com/package/@api-client-sdk-streamline-sample/products-api-client) | ||
- [Users SDK Package](https://www.npmjs.com/package/@api-client-sdk-streamline-sample/users-api-client) | ||
|
||
For more information about this automation, refer to the official [changesets documentation](https://github.com/changesets/changesets/blob/main/docs/automating-changesets.md) | ||
## Development | ||
|
||
### npm | ||
```bash | ||
# Install dependencies | ||
npm install | ||
|
||
If you want to publish package to the public npm registry and make them publicly available, this is already setup. | ||
# Start development servers | ||
npm dev | ||
|
||
To publish packages to a private npm organization scope, **remove** the following from each of the `package.json`'s | ||
# Run tests | ||
npm test | ||
|
||
```diff | ||
- "publishConfig": { | ||
- "access": "public" | ||
- }, | ||
# Build all packages | ||
npm build | ||
``` | ||
|
||
### GitHub Package Registry | ||
## Notes | ||
|
||
While demonstrated in a monorepo, in a real-world scenario, each API might be a separate microservice, rather than being part of a monorepo. In this case, the following aspects of the demonstrated workflow would still be applicable: | ||
|
||
See [Working with the npm registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry#publishing-a-package-using-publishconfig-in-the-packagejson-file) | ||
- SDK Distribution: The `publish-sdk.yml` workflow can be used to distribute the generated SDKs via NPM, making them accessible to client applications. | ||
- Reusable Client Configuration: The `api-client-config` approach can be adopted to provide a reusable client configuration, simplifying the integration process for client applications. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.* | ||
.yarn/* | ||
!.yarn/patches | ||
!.yarn/plugins | ||
!.yarn/releases | ||
!.yarn/versions | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# env files (can opt-in for committing if needed) | ||
.env* | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). | ||
|
||
## Getting Started | ||
|
||
First, run the development server: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
# or | ||
bun dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. | ||
|
||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. | ||
|
||
## Learn More | ||
|
||
To learn more about Next.js, take a look at the following resources: | ||
|
||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
|
||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! | ||
|
||
## Deploy on Vercel | ||
|
||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
|
||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { NextResponse } from 'next/server' | ||
import logger from '@/lib/api-client-config/logger' | ||
import { handleApiError } from '@/lib/api-client-config/errors/handler' | ||
import { getProductsApi } from '@/lib/api-client-config/api-factory' | ||
|
||
export async function GET() { | ||
try { | ||
logger.info('Starting GET request to /api/products') | ||
const productsApi = getProductsApi() | ||
const products = await productsApi.productsControllerFindAll() | ||
logger.debug({ products }, 'Products retrieved successfully') | ||
return NextResponse.json(products) | ||
} catch (error) { | ||
return handleApiError(error) | ||
} | ||
} | ||
|
||
export async function POST() { | ||
try { | ||
logger.info('Starting POST request to /api/products') | ||
const productsApi = getProductsApi() | ||
const newProduct = await productsApi.productsControllerCreate({ | ||
createProductDto: { | ||
name: "Sample Product", | ||
price: 29.99, | ||
description: "A test product", | ||
categories: ["test"] | ||
} | ||
}) | ||
logger.debug({ newProduct }, 'Product created successfully') | ||
return NextResponse.json(newProduct) | ||
} catch (error) { | ||
return handleApiError(error) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { NextResponse } from 'next/server' | ||
import logger from '@/lib/api-client-config/logger' | ||
import { handleApiError } from '@/lib/api-client-config/errors/handler' | ||
import { getUsersApi } from '@/lib/api-client-config/api-factory' | ||
|
||
export async function GET() { | ||
try { | ||
logger.info('Starting GET request to /api/users') | ||
const usersApi = getUsersApi() | ||
const users = await usersApi.usersControllerFindAll() | ||
logger.debug({ users }, 'Users retrieved successfully') | ||
return NextResponse.json(users) | ||
} catch (error) { | ||
return handleApiError(error) | ||
} | ||
} | ||
|
||
export async function POST() { | ||
try { | ||
logger.info('Starting POST request to /api/users') | ||
const usersApi = getUsersApi() | ||
const newUser = await usersApi.usersControllerCreate({ | ||
createUserDto: { | ||
name: "Sample User", | ||
email: "[email protected]", | ||
phone: "000-000-0000" | ||
} | ||
}) | ||
logger.debug({ newUser }, 'User created successfully') | ||
return NextResponse.json(newUser) | ||
} catch (error) { | ||
return handleApiError(error) | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
:root { | ||
--background: #ffffff; | ||
--foreground: #171717; | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
--background: #0a0a0a; | ||
--foreground: #ededed; | ||
} | ||
} | ||
|
||
body { | ||
color: var(--foreground); | ||
background: var(--background); | ||
font-family: Arial, Helvetica, sans-serif; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type { Metadata } from "next"; | ||
import { Geist, Geist_Mono } from "next/font/google"; | ||
import "./globals.css"; | ||
|
||
const geistSans = Geist({ | ||
variable: "--font-geist-sans", | ||
subsets: ["latin"], | ||
}); | ||
|
||
const geistMono = Geist_Mono({ | ||
variable: "--font-geist-mono", | ||
subsets: ["latin"], | ||
}); | ||
|
||
export const metadata: Metadata = { | ||
title: "Create Next App", | ||
description: "Generated by create next app", | ||
}; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<html lang="en"> | ||
<body | ||
className={`${geistSans.variable} ${geistMono.variable} antialiased`} | ||
> | ||
{children} | ||
</body> | ||
</html> | ||
); | ||
} |
Oops, something went wrong.