GithubHelp home page GithubHelp logo

honojs / hono Goto Github PK

View Code? Open in Web Editor NEW
17.2K 17.2K 484.0 6.17 MB

Web framework built on Web Standards

Home Page: https://hono.dev

License: MIT License

JavaScript 0.57% TypeScript 99.41% Dockerfile 0.02%
aws-lambda bun cloudflare cloudflare-workers deno npm router typescript web-framework

hono's People

Contributors

ariskemper avatar code-hex avatar cometkim avatar dario-piotrowicz avatar edamame-x avatar equt avatar exoego avatar fzn0x avatar goisaki avatar hagishi avatar jamesarosen avatar jkeys089 avatar metrue avatar mosle avatar mvares avatar nakasyou avatar namesmt avatar naporin0624 avatar ryuapp avatar sizumita avatar sor4chi avatar taishinaritomi avatar tani avatar thatonebro avatar usualoma avatar watany-dev avatar yasuaki640 avatar yudai-nkt avatar yujonglee avatar yusukebe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hono's Issues

Detach middleware from main package.

Hono package became too fat because including builtin middleware. So, we should detach middleware from Hone main package. We can use exports in package.json. For example :

  "exports": {
    ".": "./dist/index.js",
    "./powered-by": "./dist/middleware/powered-by/powered-by.js"
  }
import { Hono } from 'hono'
import { poweredBy } from 'hono/poweredBy'

...

app.use('*', poweredBy())

I don't know it will be well. We should try it.

Develop under the organization?

Now Hono is developed in yusukebe/hono. But:

  • Project is getting bigger.
  • There are some related projects such as "starter template", "for the website", and "examples"...

So, It is a good idea to make the organization for Hono. And transfer this project under the organization.

Webpack 5 polyfills are not included for node.js

Webpack 4 that is used in current version wrangler has polyfills for Node.js like Buffer or crypto. But, Webpack 5 polyfill are not included. Then, basic-auth middleware is not working in other environments such as wrangler 2.0 default settings.

One of the ways is basic-auth middleware imports Buffer and crypto. In mustache middleware, it imports mustache dynamically like this: https://github.com/yusukebe/hono/blob/d3a6f2cdf79deeff6e147d14353971425e74ecbf/src/middleware/mustache/mustache.ts#L11

If users want to use basic-auth middleware, they should install Buffer and crypto.

Project Logo

I want a project logo image! A cool image for Hono! Is there anyone who can design and draw it?

Deploy Hono app in GitHub Action

Since hono is using wrangler@beta, so we can not use the official action wrangler-action since it is still in version 1.x.x.

And I tried with script,

name: workers

on:
  push:
    branches:
      - production
jobs:
  deploy:
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.7.0
      - name: publish
        run: |
          cd api;
          npx wrangler@beta publish index.js;
        env:
          CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}

It complains with error log,

cd api;
  npx wrangler@beta publish index.js;
  shell: /usr/bin/bash -e {0}
  env:
    CF_API_TOKEN: ***
npm WARN exec The following package was not found and will be installed: wrangler@beta
Using "CF_API_TOKEN" environment variable. This is deprecated. Please use "CLOUDFLARE_API_TOKEN", instead.
 ⛅️ wrangler 0.0.2[7](https://github.com/gikiapp/giki.api/runs/6211614457?check_suite_focus=true#step:4:7) 
--------------------
No account id found, quitting...

If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new.
Error: Process completed with exit code 1.

Any idea to solve this?

TODO

  • Support wrangler2
  • expressjs like req/res handling
  • Benchmark
  • Try on Fastly Compute@Edge
  • Template project of Cloudflare Workers Later
  • npmignore
  • mime-type
  • any all
  • Try on Deno deploy
  • Example for JSX https://nanojsx.github.io #30
  • Chainable route
  • Return method not allowed
  • base path
  • Support middleware
  • TypeScript maked.ts JSDoc
  • TypeScript #21
  • Try on TypeScript It works!
  • mimify Later
  • SSR with assetKV
  • Error handling
  • Error log
  • Custom Error message
  • Error handling - Middleware should be async function
  • redirect
  • c.respond
  • ``app.use(router.routes());`
  • multi middleware
  • Test with edge-mock #18
  • Contribution Guide
  • Add keywords to package.json
  • Documentation
  • Config
  • return JSON c.json()
  • files field in package.json
  • Cloudflare Durable Objects
  • Cloudflare KV #60
  • Render HTML with template engine Use JSX SSR
  • Content-Length
  • Lint #27
  • Promotion
  • More practical example
  • example serving static #61
  • Try test with miniflare2
  • c.redirect #36
  • Support Module Workers?
  • c.notFound use c.text('not found', 404)
  • c.json({}, 200, {'x-custom-header': 'value'}) #34
  • Development / Production... mode?
  • FetchEvent instance as c.req.event
  • How to test app example
  • Try esbuild
  • c.notFound() ?
  • websockets
  • const res = c.text('a'); res.headers.set() is good way? #62

Middleware

  • Logger #11
  • Basic Auth #28
  • CORS #53
  • body-parse #38
  • X-Response-Time
  • Cookie #64

Write documents in better English

My english is poor 😥 please write documents in better English. For examples:

  • README
    • What is Hono
    • Features
    • Usage
    • API
    • Demo
    • With Cloudflare Workers
    • With Fastly Compute@Edge
  • Usage of middleware src/middleware/powered-by/README.md
  • How to run example examples/basic/README.md

Env is not available in ctx in Service Worker mode

In Cloudflare Worker, we can set environment variables in wrangler.toml, but I found that it's not accessible when we use Hono in Service Worker mode (app.fire()).

Module Worker mode like following works well.

export default {
  fetch(request, env, event) {
    return app.fetch(request, env, event)
  },
}

I am thinking if we can make environment variables works in app.fire() , it'd be great.

`Context.get` `Context.set`

For data sharing.

const app = new Hono()

app.use('*', async (c, next) => {
  c.set('name', 'foo')
  await next()
})

app.get('/', (c) => {
  const foo = c.get('name')
  return c.text(`Hello ${foo}!`)
})

Build error when import builtin middlewares

It seems like the builtin middlewares not included correctly in release package (version 0.5.1)

import { Hono } from 'hono'
import { basicAuth } from 'hono/basicAuth'

const app = new Hono()

app.use('/api/talks', basicAuth())
app.get('/', (c) => {c.json({})}) 
./index.js
Module not found: Error: Can't resolve 'hono/basicAuth' in '/Users/minhuang/Development/Projects/giki.api/services/talks/create'
resolve 'hono/basicAuth' in '/Users/minhuang/Development/Projects/giki.api/services/talks/create'
  Parsed request is a module

default or wildcard route

Is there any way to create a default or wildcard route? For example, if I want to build a custom 404 handler, I can't seem to be able to do it.

Example I thought would work:

app.get("/api/abc", handleAbcRoute);
app.get("/api/*", handleCustom404);

However, the last wildcard route always takes precedence. There seems to be no way for the first route to be handled appropriately and all other routes use the handleCustom404 function.

Roadmap to v1.3.0

I don't know if we will do all things. These are just ideas.

  • Support Deno #184 Later
  • Context.get Context.set #205
  • HonoRequest #213 Later
  • deprecate Route #237

How to structure large apis using hono?

Traditionally using express I would have this file structure:

── routes
    ├── index.js
    ├── users.route.js
── index.js  

And then in users.route.js I would define all my routes relating to users e.g.

const router = express.Router();

router
  .route('/')
  .post(auth('manageUsers'), validate(userValidation.createUser), userController.createUser)
  .get(auth('getUsers'), validate(userValidation.getUsers), userController.getUsers);

router
  .route('/:userId')
  .get(auth('getUsers'), validate(userValidation.getUser), userController.getUser)
  .patch(auth('manageUsers'), validate(userValidation.updateUser), userController.updateUser)
  .delete(auth('manageUsers'), validate(userValidation.deleteUser), userController.deleteUser);

module.exports = router;

In routes/index.js I would apply the base urls to all my defined routes and then in the top level index.js I would import and enable them:

// v1 api routes
app.use('/v1', routes);

What is the recommended way of doing this in Hono?

Can basic-auth middleware support Fastly Compute@Edge?

Most features of Hono work on Fastly Compute@Edge. Here is example:
https://github.com/yusukebe/hono/tree/master/example/compute-at-edge

That's great Hono supports both Cloudflare Workers and Compute@Edge. But, basic-auth middleware does not work on Compute@Edge because it does not provides crypto.

SS

The code I tried is here:

app.use('/auth', Middleware.basicAuth({ username: 'user', password: 'pass' }))

Can basic-auth middleware support Fastly Compute@Edge? We can do it with polyfill? Using digest.hash_sha256 in C@E? If it is difficult to support C@E without dependencies, let us give up. Because, Hono must not depends any modules.

If anyone knows, let me know.

Discussion: hono.use

The current handler and middleware design of Hono is great, and I am thinking the possibility to make it a little simpler and cleaner.

  • Make the handler and middleware one the same thing, and both apply by hono.use
const middleware = async (ctx, next) => {
   // middleware functionality code
   await  next()
}

const handler = async (ctx) => {
   ctx.body = 'hello world'
}

Then we can apply them with chained style,

new Hono().use(middleware).use(handler)

or compose style,

new Hono().use(middleware, handler)
  • Router acts routing responsibility

Hono's routers (TrieRouter and RegExpRouter) are so cool with high performance as we see in Hono currently, to better support hono.use mentioned above, we can extend it a little bit to be like,

const router = new TrieRouter()
router
    .get('/', (ctx) => ctx.body = 'ok')
    .post('/', (ctx) => ctx.body = {'status': 'created'})
    ...

Then Hono can just apply it likem

hono.use(router.routes())

Does this sound like an idea worth discussing?

`HonoRequest`

To make that Response supports the shortcuts such as c.req.param, c.req.query, and c.req.header, we use declare global.

declare global {
  interface Request<ParamKeyType = string> {
    param: (key: ParamKeyType) => string
    query: (key: string) => string
    header: (name: string) => string
  }
}

This is good, but not better. We can use these methods in the Hono app, but in other environments, a Request object does not have params, query, and header, naturally.

So, I'm planning to make HonoRequest extending Request object. It is not necessary to make HonoResponse.

Add example with Miniflare/Wrangler2

I'd love to see an official example with Miniflare with live reloading for development mode.

I've put together my own project that was working with Miniflare 2.0.0 and Hono 0.0.13. However, if I update Miniflare to 2.2.0, it no longer works. Miniflare shows this on the durable object example:

[mf:err] GET /api/: TypeError: Failed to parse URL from [object Object]
    at new Request (/Users/jn/Apps/project-api/node_modules/undici/lib/fetch/request.js:83:23)
    at new Request (/Users/jn/Apps/project-api/node_modules/miniflare/node_modules/@miniflare/core/src/standards/http.ts:398:13)
    at EventTarget.dispatchFetch (/Users/jn/Apps/project-api/node_modules/miniflare/node_modules/@miniflare/core/src/index.ts:999:51)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Server.<anonymous> (/Users/jn/Apps/project-api/node_modules/@miniflare/http-server/src/index.ts:167:20)

Tests are failed on Node v18.x

Throw the errros about crypto on Node v18.x

 FAIL  src/utils/jwt/jwt.test.ts
  ● JWT › HS256 sign & verify & decode

    TypeError: Value of "this" must be of type SubtleCrypto

      73 |   alg: AlgorithmTypes = AlgorithmTypes.HS256
      74 | ): Promise<ArrayBuffer> => {
    > 75 |   const cryptoKey = await crypto.subtle.importKey(
         |                                         ^
      76 |     CryptoKeyFormat.RAW,
      77 |     utf8ToUint8Array(secret),
      78 |     param(alg),

      at signing (src/utils/jwt/jwt.ts:75:41)
      at Object.sign (src/utils/jwt/jwt.ts:95:64)
      at Object.<anonymous> (src/utils/jwt/jwt.test.ts:74:17)
...

TODO 2

Routing

  • Deprecate chained route? #105
  • Support nested(like) routing? #105
  • One handler
  • noMatch
  • RegExpRouter as default?

  • Web sites?
  • Stacktrace #158
  • Fix API
  • Promotion
  • How to test app / example
  • Add project template to Cloudflare QuickStart
  • Web Sockets
  • Determine Cloudflare or Compute@Edge or not
  • Dynamic import / lazy load third party modules if really want to use some Middleware
  • Image logo #153
  • Documentation #71
  • README
  • Document in Japanese #131
  • Badges on README 68baca0
  • View
  • slurp content from files in KV #72
  • source map
  • uglify
  • custom error object #111
  • app.onError #111
  • Customize error message #111
  • DEBUG flag?
  • Error handling: => app.get('/', (c) => 'Hello Hono!')
  • Debugging`
  • Redirect trailing slash?
  • Return method not allowed
  • c.stash ?
  • 405 method not allowed
  • c.render with other middleware
  • Obsolete chained route and c.route ??
  • TypeError: c.req.header is not a function
  • Cache-Control for serve-static
  • set HTTP statusText automatically
  • Fix examples #101
  • Durable Objects example
  • Benchmark for Compute@Edge
  • Rewrite test for blog. Using jest-miniflare
  • Do not include tests into NPM package?
  • pretty option on c.json #150
  • About TypeScript in Japanese README
  • types.ts
  • Directory structure

Middleware

  • Serve Static for Cloudflare cf-static serve-static #76
  • Basic Auth support Compute@Edge? #86
  • Basic auth support multiple users #112
  • throw error if basic auth user/pass is not set #112
  • Favicon ?
  • compress
  • Etag #119
  • GraphQL
  • View with mustache #72
  • View with React
  • Stack trace
  • logger use waituntil?
  • parsedBody as any?
  • stack trace in graphql

Not sure

  • Development / Production mode?
  • Try esbuild

How do you create middleware for a specific route and method?

Say I wanted to validate the parameters for a post request using middleware but not affect the other methods like get etc, I would like to be able to do:

const route = app.route('/users')
route.post('/', validate(userValidation.createUser), userController.createUser)

But that isn't possible, the only way I can see to do it currently is:

const route = app.route('/users')
app.user('/users', validate(userValidation.createUser))
route.post('/', userController.createUser)

But this does it for all methods in the /users route, I could check in the middleware for the route method but this isn't ideal. Is there a way to do this that I am missing?

TODO 3

  • docs: about testing
  • docs: reg-exp-router
  • Build a website for Hono?? #359
  • docs: about Module Worker for Cloudflare Workers
  • docs: In README, more detail about middleware

Not Sure

  • Request => HonoRequest / Response => HonoResponse

Readmap to v1.2.0

  • Handler and middlewares are treated as the same things #193
  • app.route(path, Route) #203
  • Multi match trie-router #196
  • Multi match reg-exp-router #220
  • Write document

Document for `Env` variables

Write a document on how to handle Environment variables for Cloudflare Workers. Like this:

app.post('/posts', async (c, next) => {
  const auth = basicAuth({ username: c.env.NAME, password: c.env.PASS })
  await auth(c, next)
})

Anyway to access an object for query parameters and url parameters?

I know you can access all the parameters in a url, www.url.com/?param1=hey&param2=three, by doing:

c.req.query('param1')
c.req.query('param2')

But is there anyway of just accessing an object for all the available parameters without having to know their names in advance?

Proposal: Stacked routes as middleware

I've noticed that we don't have a smart API for the application with a large structure. It's related to #200
So, I propose yet another way for routing. That is stacking routes and using these as middleware.

import { Hono, Route } from 'hono'

const app = new Hono()
const route = new Route()

route.get('/entry', handler, handler).post(handler, handler)

app.use('/v1', route)
app.fire()

The routers TrieRouter and RegExpRouter do not have routes like a stack but tree. So, we can't use the ways directly, and we have to make the object to stack routes. Route object is for stacking in the above code.

It's just the idea. If you have comments, please tell me.

Deno support??

I'm trying to see Hono works on Deno. Even if I can, the project files, etc. will maybe get more complicated. So finding a better way. I will give up if it is not found.

Do not calculate `Content-Length`

I notice that calculating Content-Length makes returning a response slowly.

This section:

    let length = 0
    if (data) {
      if (data instanceof ArrayBuffer) {
        length = data.byteLength
      } else if (typeof data == 'string') {
        const Encoder = new TextEncoder()
        length = Encoder.encode(data).byteLength || 0
      }
    }

Wrangler, Miniflare, or Cloudflare calculate Content-Length and add to a header automatically. So, we do not have to do it by ourselves. So, how about removing this section?

If we remove it, logger middleware can not show Content-Length.

"Logger" builtin middleware

We want to have "Logger" middleware as a builtin middleware. We have to write middleware with no dependency on any other npm modules. To know how to write middleware, see Powered By middleware:

const poweredBy = async (c, next) => {
 await next()
 await c.res.headers.append('X-Powered-By', 'Hono')
}

After we wrote middleware, add the method to Middleware object:

Middleware.poweredBy = poweredBy

And then, we can use middleware like this:

const { Hono, Middleware } = require('hono')
...
app.use('*', Middleware.poweredBy)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.