Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to separate itty-router from openapi logic #151

Merged
merged 11 commits into from
Jun 18, 2024
Merged

Conversation

G4brym
Copy link
Member

@G4brym G4brym commented May 24, 2024

This refactors the OpenAPI logic and adds support for latest versions of itty-router and possibly other router (like hono)

The new version will require users to instantiate their own itty-router router like:

import { fromIttyRouter } from '@cloudflare/itty-router-openapi'
import { AutoRouter } from 'itty-router'
import { ToDoGet } from './todo'

const openapiRouter = fromIttyRouter(AutoRouter())
openapiRouter.get('/todo', ToDoGet)

export default openapiRouter

Breaking changes:

  • removed OpenAPIRouter() method
  • removed aiPlugin option
  • removed skipValidation option (see new validation method bellow)
  • itty-router is no longer a dependency and users must manually add it to their project
  • validated data is no longer send in the last argument of the handler function (see new validation method bellow)
  • Endpoint's schema is no longer a static variable
  • Endpoint's schema.parameters was renamed to schema.request to follow zod-to-openapi structure
  • Endpoint Path parameters are now called params to match the validated Data object name
  • Endpoint's schema.requestBody was renamed to schema.request.body to follow zod-to-openapi structure
  • Validation no longer occurs before the endpoint's handle function is called, developers must manually call the getValidatedData to execute the data validation step
    • Tip: you can wrap this function call with try {} catch (e) {} to handle input errors, otherwise this library will return the errors in a Json response with http 400

Additions:

  • new await this.getValidatedData<typeof this.schema>() method to retrieve all validated data, when sending <typeof this.schema> in the generic the returned value will have full typescript inference based on the schema
  • automatically coerce all headers, query and params inputs based on specified zod type
  • new fromIttyRouter() instantiate method
  • new fromHono() instantiate method

Migration guide:

  • install latest version
  • install latest itty-router version (npm install itty-router@latest --save)
  • replace your current router instance
    • from: const router = OpenAPIRouter({...})
    • to: const router = fromIttyRouter(Router(), {...})
  • remove the new from all "legacy type" call from new Str(...) into Str(...)
  • remove the data argument from your endpoint's handle function
    • from: async handle(request: Request, env: Env, ctx: Context, data: any) {...}
    • to: async handle(request: Request, env: Env, ctx: Context) {...}
  • add this variable to the first line of your endpoint handle function const data = await this.getValidatedData<typeof this.schema>()
  • remove the static keyword from the endpoints schema property from:static schema to: schema
  • move query parameters from schema.parameters.query into schema.request.query
  • move path parameters from schema.parameters.path into schema.request.params
  • move headers parameters from schema.parameters.headers into schema.request.headers
  • wrap your query, headers and params into a zod object z.object({...})
  • move you schema.requestBody into schema.request.body: contentJson(z.object({...params.newModel}))

Minimal Hono example

import { extendZodWithOpenApi, fromHono, OpenAPIRoute } from '@cloudflare/itty-router-openapi'
import { Hono } from 'hono'
import { z } from 'zod'

extendZodWithOpenApi(z)

export class GetPageNumber extends OpenAPIRoute {
  schema = {
    request: {
      params: z.object({
        id: z.string().min(2).max(10),
      }),
      query: z.object({
        page: z.number().int().min(0).max(20),
      }),
    },
  }

  async handle(c) {
    const data = await this.getValidatedData<typeof this.schema>()

    return c.json({
      id: data.params.id,
      page: data.query.page,
    })
  }
}


const app = new Hono()
const openapi = fromHono(app)

openapi.get('/entry/:id', GetPageNumber)
export default app

Copy link

github-actions bot commented May 24, 2024

🧪 A prerelease is available for testing 🧪

You can install this latest build in your project with:

npm install --save https://prerelease-registry.devprod.cloudflare.dev/itty-router-openapi/runs/9555081565/npm-package-itty-router-openapi-151

Or you can immediately run this with npx:

npx https://prerelease-registry.devprod.cloudflare.dev/itty-router-openapi/runs/9555081565/npm-package-itty-router-openapi-151

@carafelix
Copy link

carafelix commented Jun 6, 2024

That's great!
From a quick glance, it looks like the current openAPIRoute's would be compatible with this new version, that's good news on my book, since that could have been the main migration cost.
Gotta say, the class based endpoints it's a beautiful abstraction. That's mostly why I prefer this package over hono-zod. It makes much more sense to encapsulate the handler with the schema, than the route with the schema. And I have not found any other router with this capabilities.
I know this is not a very contributing comment, but nevertheless, sometimes, a few honest words are good to keep up the spirit, and therefore, keep the good work coming down the river.
I can see this package becoming a standard for api development.

@G4brym G4brym force-pushed the refactor-version-2 branch 4 times, most recently from a8cc538 to 16ae377 Compare June 9, 2024 15:18
@G4brym G4brym force-pushed the refactor-version-2 branch 3 times, most recently from 7151dc9 to e93663d Compare June 17, 2024 21:30
@G4brym G4brym force-pushed the refactor-version-2 branch 2 times, most recently from 4cedb31 to f3fd898 Compare June 17, 2024 22:29
@G4brym G4brym force-pushed the refactor-version-2 branch 2 times, most recently from 7ce627b to 9c23342 Compare June 18, 2024 10:10
@G4brym G4brym marked this pull request as ready for review June 18, 2024 18:02
@G4brym G4brym merged commit 1a090a5 into main Jun 18, 2024
3 checks passed
@G4brym G4brym deleted the refactor-version-2 branch June 18, 2024 18:03
@carafelix
Copy link

carafelix commented Jun 18, 2024

Awesome! I'll check the new stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants