core
core copied to clipboard
Support multiple bindings (databases/kv)
Is your feature request related to a problem? Please describe. Right now NuxtHub adds a single binding for whatever feature is enabled in the config with a hardcoded binding name.
Describe the solution you'd like
It would be nice if an array could be specified alongside the boolean to allow multiple bindings, and access them by specifying them within the hubX() util.
Old code example
export default defineNuxtConfig({
hub: {
kv: [
{
binding: "CONFIG",
id: "abcdefg"
},
{
binding: "ANOTHER",
id: "foobar"
}
],
database: true
},
})
const anotherKeys = await hubKV("ANOTHER").keys()
const keys = await hubKV().keys() // would use the default binding
Here's another more configurable potential option which covers everything from fully NuxtHub managed single binding, to fully custom user managed multiple bindings, and everything in between.
export default defineNuxtConfig({
hub: {
/**
* Database
*/
// default database that NuxtHub creates
database: true,
// default custom database across all environments
// during local development and preview, NuxtHub use the same database
database: 'your-database-id',
// default custom database for production only
// during local development and preview (omitted envs), NuxtHub creates a new database
database: {
default: { production: 'your-database-id' }
},
// multiple database bindings via different methods
database: {
default: { production: 'your-database-id' },
db: true, // will error, can't have default and DB at the same time - they're the same
prices: 'your-database-id' // binding added as PRICES, used via hubDatabase('prices')
},
/**
* R2 & KV
*/
// same concept as database
/**
* Vectorize
*/
// user needs to create metadata indexes via cli
// handling creation of (metadata) indexes etc. is far too complex for via config imo
vectorize: {
products: {
production: 'your-vectorize-id',
preview: 'your-vectorize-id',
development: 'your-vectorize-id'
},
reviews: {
production: 'your-vectorize-id',
preview: 'your-vectorize-id',
development: 'your-vectorize-id'
}
},
/**
* Other bindings
*/
bindings: {
hyperdrive: {
// <BINDING_NAME>: <HYPERDRIVE_ID>
POSTGRES: 'your-hyperdrive-id'
}
}
}
})
Hey @RihanArfan
We indeed imagined the ability to switch between bindings but I did not want to make it too complex to start with, it's very rare the need for multiple databases / KV / R2 and also it may also complexify the admin.
But if we have to work on it, I would see it this way:
export default defineNuxtConfig({
hub: {
database: {
// alias: BINDING
default: 'DB', // always added
users: 'USERS'
}
},
})
Then you can do:
const db = hubDatabase() // default
const usersDb = hubDatabase('users')
We should not have to specify any ID as NuxtHub should take care of this for us.
Hey @Atinux,
Your proposal looks really good to me. I just wanted to add some notes because I think there are definitely use cases where it makes sense to have multiple D1 instances, for example. Since D1 has a maximum limit of 10 GB (see D1 Limit Documentation), it might be useful to split data into multiple databases. Another use case could be to use one database for each customer in an application.
@nicogenz the main issue for having a use case as "one database for each user" is that you cannot add new database at runtime and you actually need to rebuild your website for the bindings to take effect.
@atinux, Can we also explore multiple R2 buckets per project? For multi-tenant SaaS, isolating file uploads to separate R2 buckets per tenant is crucial for accurate cost mapping.
Looks like dynamic bindings is coming to Vectorize in Q1 2025, and I guess other services may get this too
+1 for multiple db bindings. I'd like to keep my logs and other large debug/history tables in a seperate db to make sure I don't come up against the 10GB limit. So ideally I'd like to be able to decide at runtime which db to insert against. Thanks!
+1 for multiple bindings, would be great to use this for having a local test database different from my local database - allowing me to have a db sandbox for e2e testing for endpoints
+1 multiple bindings: https://github.com/nuxt-hub/core/issues/488 @atinux Use case: Nuxt 3 monorepo with different layers such as CMS, Ecommerce, Logs, etc. Not thousands per user that doesn't require creation in runtime, but still necessary to separate logic, especially in cases when the layers could be dynamically enabled/disabled for SaaS purposes.
Is it possible to do the binding on the fly using the rest api's? First the create the d1 and then bind it to the worker?
This is really the only thing stopping me from using Nuxt Hub / Cloudflare.