UNPKG

7.84 kBMarkdownView Raw
1# cacheable-lookup
2
3> A cacheable [`dns.lookup(…)`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback) that respects TTL :tada:
4
5[![Node CI](https://github.com/szmarczak/cacheable-lookup/workflows/Node%20CI/badge.svg)](https://github.com/szmarczak/cacheable-lookup/actions)
6[![codecov](https://codecov.io/gh/szmarczak/cacheable-lookup/branch/master/graph/badge.svg)](https://codecov.io/gh/szmarczak/cacheable-lookup)
7[![npm](https://img.shields.io/npm/dm/cacheable-lookup.svg)](https://www.npmjs.com/package/cacheable-lookup)
8[![install size](https://packagephobia.now.sh/badge?p=cacheable-lookup)](https://packagephobia.now.sh/result?p=cacheable-lookup)
9
10Making lots of HTTP requests? You can save some time by caching DNS lookups :zap:
11
12## Usage
13
14### Using the `lookup` option
15
16```js
17import http from 'node:http';
18import CacheableLookup from 'cacheable-lookup';
19
20const cacheable = new CacheableLookup();
21
22http.get('http://example.com', {lookup: cacheable.lookup}, response => {
23 // Handle the response here
24});
25```
26
27### Attaching CacheableLookup to an Agent
28
29```js
30import http from 'node:http';
31import https from 'node:https';
32import CacheableLookup from 'cacheable-lookup';
33
34const cacheable = new CacheableLookup();
35
36cacheable.install(http.globalAgent);
37cacheable.install(https.globalAgent);
38
39http.get('http://example.com', response => {
40 // Handle the response here
41});
42```
43
44## API
45
46### new CacheableLookup(options)
47
48Returns a new instance of `CacheableLookup`.
49
50#### options
51
52Type: `object`\
53Default: `{}`
54
55Options used to cache the DNS lookups.
56
57##### cache
58
59Type: `Map` | [`Keyv`](https://github.com/lukechilds/keyv/)\
60Default: `new Map()`
61
62Custom cache instance. If `undefined`, it will create a new one.
63
64**Note**: If you decide to use Keyv instead of the native implementation, the performance will drop by 10x. Memory leaks may occur as it doesn't provide any way to remove all the deprecated values at once.
65
66**Tip**: [`QuickLRU`](https://github.com/sindresorhus/quick-lru) is fully compatible with the Map API, you can use it to limit the amount of cached entries. Example:
67
68```js
69import http from 'node:http';
70import CacheableLookup from 'cacheable-lookup';
71import QuickLRU from 'quick-lru';
72
73const cacheable = new CacheableLookup({
74 cache: new QuickLRU({maxSize: 1000})
75});
76
77http.get('http://example.com', {lookup: cacheable.lookup}, response => {
78 // Handle the response here
79});
80```
81
82##### options.maxTtl
83
84Type: `number`\
85Default: `Infinity`
86
87The maximum lifetime of the entries received from the specifed DNS server (TTL in seconds).
88
89If set to `0`, it will make a new DNS query each time.
90
91**Pro Tip**: This shouldn't be lower than your DNS server response time in order to prevent bottlenecks. For example, if you use Cloudflare, this value should be greater than `0.01`.
92
93##### options.fallbackDuration
94
95Type: `number`\
96Default: `3600` (1 hour)
97
98When the DNS server responds with `ENOTFOUND` or `ENODATA` and the OS reports that the entry is available, it will use `dns.lookup(...)` directly for the requested hostnames for the specified amount of time (in seconds).
99
100**Note**: You should avoid setting this to `0` unless the provided DNS servers' database is limited to few domains.
101
102##### options.errorTtl
103
104Type: `number`\
105Default: `0.15`
106
107The time how long it needs to remember queries that threw `ENOTFOUND` or `ENODATA` (TTL in seconds).
108
109**Note**: This option is independent, `options.maxTtl` does not affect this.
110
111**Pro Tip**: This shouldn't be lower than your DNS server response time in order to prevent bottlenecks. For example, if you use Cloudflare, this value should be greater than `0.01`.
112
113##### options.resolver
114
115Type: `dns.Resolver | dns.promises.Resolver`\
116Default: [`new dns.promises.Resolver()`](https://nodejs.org/api/dns.html#dns_class_dns_resolver)
117
118An instance of [DNS Resolver](https://nodejs.org/api/dns.html#dns_class_dns_resolver) used to make DNS queries.
119
120##### options.lookup
121
122Type: `Function`\
123Default: [`dns.lookup`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback)
124
125The fallback function to use when the DNS server responds with `ENOTFOUND` or `ENODATA`.
126
127If you don't query internal hostnames (such as `localhost`, `database.local` etc.), it is strongly recommended to set this to `false`.
128
129### Entry object
130
131Type: `object`
132
133#### address
134
135Type: `string`
136
137The IP address (can be an IPv4 or IPv6 address).
138
139#### family
140
141Type: `number`
142
143The IP family (`4` or `6`).
144
145##### expires
146
147Type: `number`
148
149**Note**: This is not present when falling back to `dns.lookup(...)`!
150
151The timestamp (`Date.now() + ttl * 1000`) when the entry expires.
152
153#### ttl
154
155**Note**: This is not present when falling back to `dns.lookup(...)`!
156
157The time in seconds for its lifetime.
158
159#### source
160
161**Note**: This is not present when falling back to `dns.lookup(...)`!
162
163Whether this entry was loaded from the cache or came from a query (`cache` or `query`)
164
165### Entry object (callback-style)
166
167When `options.all` is `false`, then `callback(error, address, family, expires, ttl)` is called.\
168When `options.all` is `true`, then `callback(error, entries)` is called.
169
170### CacheableLookup instance
171
172#### servers
173
174Type: `Array`
175
176The DNS servers used to make queries. Can be overridden - doing so will clear the cache.
177
178#### [lookup(hostname, options, callback)](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback)
179
180#### lookupAsync(hostname, options)
181
182The asynchronous version of `dns.lookup(…)`.
183
184Returns an [entry object](#entry-object).\
185If `options.all` is true, returns an array of entry objects.
186
187##### hostname
188
189Type: `string`
190
191##### options
192
193Type: `object`
194
195The same as the [`dns.lookup(…)`](https://nodejs.org/api/dns.html#dns_dns_lookup_hostname_options_callback) options.
196
197#### query(hostname)
198
199An asynchronous function which returns cached DNS lookup entries.\
200This is the base for `lookupAsync(hostname, options)` and `lookup(hostname, options, callback)`.
201
202**Note**: This function has no options.
203
204Returns an array of objects with `address`, `family`, `ttl` and `expires` properties.
205
206#### queryAndCache(hostname)
207
208An asynchronous function which makes two DNS queries: A and AAAA. The result is cached.\
209This is used by `query(hostname)` if no entry in the database is present.
210
211Returns an array of objects with `address`, `family`, `ttl` and `expires` properties.
212
213#### updateInterfaceInfo()
214
215Updates interface info. For example, you need to run this when you plug or unplug your WiFi driver.
216
217**Note:** Running `updateInterfaceInfo()` will trigger `clear()` only on network interface removal.
218
219#### clear(hostname?)
220
221Clears the cache for the given hostname. If the hostname argument is not present, the entire cache will be emptied.
222
223## High performance
224
225Performed on:
226- Query: `example.com`
227- CPU: i7-7700k
228- CPU governor: performance
229
230```
231CacheableLookup#lookupAsync x 2,896,251 ops/sec ±1.07% (85 runs sampled)
232CacheableLookup#lookupAsync.all x 2,842,664 ops/sec ±1.11% (88 runs sampled)
233CacheableLookup#lookupAsync.all.ADDRCONFIG x 2,598,283 ops/sec ±1.21% (88 runs sampled)
234CacheableLookup#lookup x 2,565,913 ops/sec ±1.56% (85 runs sampled)
235CacheableLookup#lookup.all x 2,609,039 ops/sec ±1.01% (86 runs sampled)
236CacheableLookup#lookup.all.ADDRCONFIG x 2,416,242 ops/sec ±0.89% (85 runs sampled)
237dns#lookup x 7,272 ops/sec ±0.36% (86 runs sampled)
238dns#lookup.all x 7,249 ops/sec ±0.40% (86 runs sampled)
239dns#lookup.all.ADDRCONFIG x 5,693 ops/sec ±0.28% (85 runs sampled)
240Fastest is CacheableLookup#lookupAsync.all
241```
242
243## Related
244
245- [cacheable-request](https://github.com/lukechilds/cacheable-request) - Wrap native HTTP requests with RFC compliant cache support