Skip to content

Refactor to separate itty-router from openapi logic - #151

Merged
G4brym merged 11 commits into
mainfrom
refactor-version-2
Jun 18, 2024
Merged

G4brym merged 11 commits into
mainfrom
refactor-version-2

Conversation

@G4brym

@G4brym G4brym commented May 24, 2024 •

Copy link
Copy Markdown
Member

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

@github-actions

github-actions Bot commented May 24, 2024 •

Copy link
Copy Markdown
Contributor

🧪 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

@G4brym
G4brym force-pushed the refactor-version-2 branch from 6eee299 to 6ea2011 Compare May 27, 2024 14:21
@carafelix

carafelix commented Jun 6, 2024 •

Copy link
Copy Markdown

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 from dcafc96 to bf31198 Compare June 7, 2024 14:13
@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 from 16ae377 to 4711c09 Compare June 9, 2024 15:39
@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 force-pushed the refactor-version-2 branch from 9c23342 to dea759a Compare June 18, 2024 11:40
@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
@G4brym
G4brym deleted the refactor-version-2 branch June 18, 2024 18:03
@carafelix

carafelix commented Jun 18, 2024 •

Copy link
Copy Markdown

Awesome! I'll check the new stuff

MajorTanya added a commit to MajorTanya/itty.dev that referenced this pull request Mar 8, 2025
Project got renamed in early December to expand the supported libraries.
cloudflare/chanfana#151
MajorTanya added a commit to MajorTanya/itty.dev that referenced this pull request Mar 8, 2025
Project got renamed in early December to expand the supported libraries.
cloudflare/chanfana#151
MajorTanya added a commit to MajorTanya/itty.dev that referenced this pull request Mar 8, 2025
Project got renamed in early December to expand the supported libraries.
cloudflare/chanfana#151
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