Skip to content

Commit

Permalink
Update name
Browse files Browse the repository at this point in the history
  • Loading branch information
G4brym committed Jun 17, 2024
1 parent bc58eaa commit 4cedb31
Show file tree
Hide file tree
Showing 14 changed files with 2,133 additions and 297 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Cloudflare
Copyright (c) 2024 Cloudflare

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
201 changes: 46 additions & 155 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,203 +1,94 @@
# itty-router-openapi
# chanfana

<p align="center">
<em>OpenAPI 3 and 3.1 schema generator and validator for <a href="https://developers.cloudflare.com/workers/" target="_blank">Cloudflare Workers</a></em>
<em>OpenAPI 3 and 3.1 schema generator and validator for <a href="https://github.com/honojs/hono" target="_blank">Hono</a>, <a href="https://github.com/kwhitley/itty-router" target="_blank">itty-router</a> and more!</em>
</p>

---

**Documentation**: <a href="https://cloudflare.github.io/itty-router-openapi/">https://cloudflare.github.io/itty-router-openapi/</a>
**Documentation**: <a href="https://chanfana.pages.dev/">chanfana.pages.dev</a>

**Source Code**: <a href="https://github.com/cloudflare/itty-router-openapi/">https://github.com/cloudflare/itty-router-openapi/</a>
**Source Code**: <a href="https://github.com/cloudflare/chanfana/">github.com/cloudflare/chanfana</a>

---

[itty-router-openapi](https://github.com/cloudflare/itty-router-openapi) is a library that
extends [itty-router](https://github.com/kwhitley/itty-router), a powerful and lightweight routing system for Cloudflare
Workers, already familiar to many developers, and adds an easy-to-use and
compact [OpenAPI 3 and 3.1](https://swagger.io/specification/) schema generator and
validator.

itty-route-openapi can also have class-based routes, allowing the developer to quickly build on top of and extend other
endpoints while reusing code.
[chanfana](https://github.com/cloudflare/chanfana) **(previously known as itty-router-openapi)** is a library that adds
OpenAPI schema generation and validation to any router (<a href="https://github.com/honojs/hono" target="_blank">
Hono</a>, <a href="https://github.com/kwhitley/itty-router" target="_blank">itty-router</a>, etc), meant to be a
powerful and lightweight
library for Cloudflare Workers but runs on any runtime supported by the base router.

The key features are:

- OpenAPI 3 and 3.1 schema generator
- Parameter type hint and type check in typescript
- [Query](https://cloudflare.github.io/itty-router-openapi/user-guide/query-parameters/),
[Path](https://cloudflare.github.io/itty-router-openapi/user-guide/path-parameters/),
[Request Body](https://cloudflare.github.io/itty-router-openapi/user-guide/request-body/) and
[Header](https://cloudflare.github.io/itty-router-openapi/user-guide/header-parameters/) validator
- OpenAPI 3 and 3.1 schema generator and validator
- Query, Path, Headers and Body typescript inference
- Fully written in typescript
- Class-based endpoints
- Out of the box [OpenAI plugin support](https://cloudflare.github.io/itty-router-openapi/advanced-user-guide/openai-plugin/)
- [Drop-in replacement](https://cloudflare.github.io/itty-router-openapi/migrating-from-itty-router/) for existing itty-router applications

A template repository is available
at [cloudflare/workers-sdk](https://github.com/cloudflare/workers-sdk/tree/main/templates/worker-openapi),
with a live demo [here](https://worker-openapi-example.radar.cloudflare.com/docs).

## Why create another router library for workers?

This framework built on top of [itty-router](https://github.com/kwhitley/itty-router) and extends some of its
core features, such as adding class-based endpoints. It also provides a simple and iterative path for migrating from old
applications based on `itty-router`.

Building APIs and maintaining good documentation on the parameters and fields of your API hard. However, there is an
open standard that makes this documentation process much more effortless, called [OpenAPI](https://www.openapis.org/).

OpenAPI "defines a standard, language-agnostic interface to RESTful APIs which allows both humans and computers to
discover and understand the capabilities of the service without access to source code, documentation, or through network
traffic inspection." This allows other machines to reliably parse those definitions and use the remote APIs easily,
without additional implementation logic.

Some of the top requirements for Radar 2.0 were having better API documentation, improving the deployment lifecycle with
end-to-end testing, and making it publicly available to Cloudflare customers. OpenAPI support quickly jumped out as the
obvious choice to help us on all these fronts.

However, we struggled to find an existing OpenAPI framework that checked all our boxes:

- Easy integration with Cloudflare Workers
- Input validation for endpoints parameters
- Actual code-based schema generation (not just generated from comments or manually)
- Extend existing Hono, itty-router, etc application, without touching old routes

Since we couldn't find anything that suited us, as many engineers do, we opted for the second-best alternative: building
our own and open-source it.
## Getting started

## Quick setup

Get started fast using the `create-cloudflare` command line, just run this command to setup an initial project with
some example routes:

<!-- termynal -->

```bash
npm create cloudflare@latest hello-world -- --type openapi

---> 100%
```

Then to start the local server just run
Get started with a template with this command:

```bash
cd hello-world
wrangler dev
npm create cloudflare@latest -- --type openapi
```

## Installation

<!-- termynal -->

```bash
npm i @cloudflare/itty-router-openapi --save

---> 100%
npm i chanfana --save
```

## Example

Let's create our first class-based endpoint called TaskFetch in src/tasks.ts now.

Make sure that ‘Task' is global, otherwise you must redefine `responses.schema.task` with every endpoint.

When defining the schema, you can interchangeably use native typescript types or use the included types to set required
flags, descriptions, and other fields.
## Minimal Hono Example

```ts
import {
OpenAPIRoute,
Path,
Str,
DateOnly,
DataOf,
} from '@cloudflare/itty-router-openapi'

const Task = {
name: new Str({ example: 'lorem' }),
slug: String,
description: new Str({ required: false }),
completed: Boolean,
due_date: new DateOnly(),
}

export class TaskFetch extends OpenAPIRoute {
static schema = {
tags: ['Tasks'],
summary: 'Get a single Task by slug',
parameters: {
taskSlug: Path(Str, {
description: 'Task slug',
import { fromHono, OpenAPIRoute } from 'chanfana'
import { Hono } from 'hono'
import { z } from 'zod'

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),
}),
},
responses: {
'200': {
description: 'Task fetched successfully',
schema: {
metaData: {},
task: Task,
},
},
},
}

async handle(
request: Request,
env: any,
context: any,
data: DataOf<typeof TaskFetch.schema>
) {
// Retrieve the validated slug
const { taskSlug } = data.params

// Actually fetch a task using the taskSlug

return {
metaData: { meta: 'data' },
task: {
name: 'my task',
slug: taskSlug,
description: 'this needs to be done',
completed: false,
due_date: new Date().toISOString().slice(0, 10),
},
}
async handle(c) {
const data = await this.getValidatedData<typeof this.schema>()

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

Now initialize a new OpenAPIRouter, and reference our newly created endpoint as a regular ‘itty-router’ .get route:

```ts
import { OpenAPIRouter } from '@cloudflare/itty-router-openapi'
import { TaskFetch } from './tasks'
// Star a Hono app
const app = new Hono()

const router = OpenAPIRouter()
router.get('/api/tasks/:taskSlug/', TaskFetch)
// Setup OpenAPI registry
const openapi = fromHono(app)

// 404 for everything else
router.all('*', () => new Response('Not Found.', { status: 404 }))
// Register OpenAPI endpoints
openapi.get('/entry/:id', GetPageNumber)

export default {
fetch: router.handle,
}
// Export the Hono app
export default app
```

Finally, run `wrangler dev` and head to `/docs` our `/redocs` with your browser.

You'll be greeted with a beautiful OpenAPI page that you can use to test and call your new endpoint.

![Tutorial Example Preview](https://raw.githubusercontent.com/cloudflare/itty-router-openapi/main/docs/images/tutorial-example.png)

Pretty easy, right?

## Feedback and contributions

[itty-router-openapi](https://github.com/cloudflare/itty-router-openapi) aims to be at the core of new APIs built using
[chanfana](https://github.com/cloudflare/chanfana) aims to be at the core of new APIs built using
Workers and define a pattern to allow everyone to
have an OpenAPI-compliant schema without worrying about implementation details or reinventing the wheel.

itty-router-openapi is considered stable and production ready and is being used with
chanfana is considered stable and production ready and is being used with
the [Radar 2.0 public API](https://developers.cloudflare.com/radar/).

Currently this package is maintained by the [Cloudflare Radar Team](https://radar.cloudflare.com/) and features are
Expand Down
4 changes: 3 additions & 1 deletion jestconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
"^.+\\.(t|j)sx?$": ["ts-jest", {
"tsconfig": "./tests/tsconfig.json"
}]
},
"testRegex": "/tests/.*\\.test\\.ts$",
"collectCoverageFrom": ["src/**/*.{ts,js}"],
Expand Down
Loading

0 comments on commit 4cedb31

Please sign in to comment.