redis / ioredis

🚀 A robust, performance-focused, and full-featured Redis client for Node.js.
MIT License
14.34k stars 1.19k forks source link

No way to instantiate with url scheme with object parameter #1078

Open wraithgar opened 4 years ago

wraithgar commented 4 years ago

When instantiating ioredis you can either pass in a string or an object, the string can be a redis url (i.e. redis://localhost:5379 but there is no way to pass in a url like that when using the object form of instantiation. It would be nice to either have the existing host param recognize urls, or add an explicit url parameter so that one could instantiate ioredis with other options (like keyPrefix) and also pass in a redis url for the server to connect to.

intellix commented 4 years ago

Also noticing this. I'm using ioredis directly using the URL like:

redis://localhost:6379/0

Now I've just updated apollo-server-cache-redis they're only using the object param and I can't re-use the same ENV var without some splitting magic. Originally I was trying path as the first param is called path but realised they're not the same in this case as I get errors.

For now I'll split the args into multiple env vars but it was a little confusing

LinusU commented 3 years ago

For anyone wanting to work around this for now, something like this should help:

import Redis from 'ioredis'

function createRedisClient (uri: string, options?: Redis.RedisOptions): Redis.Redis {
  const parsed = new URL(uri)

  if (parsed.protocol !== 'redis') {
    throw new Error(`Unknown Redis protocol: ${parsed.protocol}`)
  }

  return new Redis({
    port: parsed.port === '' ? undefined : Number(parsed.port),
    host: parsed.hostname,
    username: parsed.username === '' ? undefined : parsed.username,
    password: parsed.password === '' ? undefined : parsed.password,
    ...options
  })
}

edit: actually what I posted above already works with the default constructor, at least as of version 4.27.11 🤦‍♂️

andrew-sol commented 2 years ago

It's ridiculous that this isn't supported yet.

If you're afraid of such configs:

{
  url: 'redis://:password@host:1234',
  host: 'foobar',
  port: 5678
}

and your only question is "OMG I do not understand what the actual host and port would be??!!", then, I guess, you should do the very same thing that all other DB connection libraries did: prioritize the url param and write about that in the docs.

So the url param should overwrite everything else. Super simple.

hunkydoryrepair commented 1 year ago

Is a URL parameter even still an option with version 5.x.x? The RedisOptions no longer includes string as a typescript type.