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

Extending H3EventContext with createApp #557

Closed
1 task done
kazupon opened this issue Oct 13, 2023 · 1 comment
Closed
1 task done

Extending H3EventContext with createApp #557

kazupon opened this issue Oct 13, 2023 · 1 comment

Comments

@kazupon
Copy link
Contributor

kazupon commented Oct 13, 2023

Describe the feature

We can extend H3Context with eventHandler or onRequest option of createApp:

The following can extend H3EventContext by eventHandler:

// case: extend `H3EventContext ` for auth with `eventHandler`
import { login } from './my/app'

export default defineEventHandler(async (event) => {
  const auth = await login(/* something options ... */)
  event.context.auth = auth
}

However, since this extends the H3EventContext per request, there are cases such as store or i18n where a one-time initialization is required, and we may want to extend it at app instance creation time with createApp, rather than per request.

The following is an example of initializing an i18n resource (context) in the form of a hook called only once on an app instance called onContext in the options of createApp.

import { createApp, H3EventContext, eventHandler } from 'h3'
import { CoreContext, createCoreContext, translate } from '@intlify/core'

// we can import locale messages dynamically
import en from './locales/en.json'

declare module 'h3' {
  interface H3EventContext {
    i18n: CoreContext
  }
}

// setup i18n instance via `onContext` of `createApp`
const app = createApp({
  onContext(context: H3EventContext) {
    const i18n = createCoreContext({
      locale: 'en',
      messages: {
        en,
      },
      // some i18n options here ...
    })
    // set i18n instance to context
    context.i18n = i18n
  },
})

app.use(
  '/',
  eventHandler((event) => {
    const message = translate(event.context.i18n, 'hello', { name: 'h3' })
    return message
  }),
)

For H3EventContext type definition extending, we need to think about #496 and #511

Additional information

  • Would you be willing to help implement this feature?
@kazupon kazupon changed the title Extending H3EventContext with createApp Extending H3EventContext with createApp Oct 13, 2023
@kazupon
Copy link
Contributor Author

kazupon commented Oct 13, 2023

I've found out that we can extend H3Context like express by currying as follows:

import { createServer } from 'node:http'
import { createApp, createRouter, eventHandler, toNodeListener } from 'h3'
import { createCoreContext as createIntlifyContext, translate } from '@intlify/core'

import type { AppOptions } from 'h3'
import type { CoreOptions as IntlifyOptions, CoreContext as IntlifyContext } from '@intlify/core'

declare module 'h3' {
  interface H3EventContext {
    i18n: IntlifyContext
  }
}

function useIntlify(options: IntlifyOptions = {}): AppOptions['onRequest'] {
   const i18n = createIntlifyContext(options)
   return (event) => {
     event.context.i18n = i18n
   }
}

const app = createApp({
  onRequest: useIntlify({
    locale: 'en',
    messages: {
      en: {
        hello: 'Hello {name}!'
      },
    }
  }),
})

const router = createRouter()
router.get(
  '/',
  eventHandler((event) => {
    return translate(event.context.i18n, 'hello', { name: 'h3' })
  }),
)

app.use(router)
createServer(toNodeListener(app)).listen(3000)

Okay, I'll close this issue.
Thanks for the great framework.

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

No branches or pull requests

1 participant