
Spice Up your Caching with Convoyr

Where it All Started
fetch
HttpClient
most apps including ours, those of our clients (i.e. companies not HTTP ones) and probably yours need the same interceptors, implementing interceptors can be tricky with some HTTP clients if you are not familiar with some other concepts, implementations observed in tutorials or in our clients' codebases can be error-prone or miss a couple of important edge cases, implementing the same interceptor more than once in a lifetime is a boring waste of time.
💡 The Idea Behind Convoyr
HttpClient
🐢 The Network Latency Performance Problem
🚒 Caching to the Rescue
🍺 The Freshness Problem
🤔 Why make a choice
Observable vs Promise
HTTPClient
fetch
✌️ Emit both cached & network
@Component({
template: `{{ weather | json }}`
})
export class WeatherComponent {
weather: Weather;
...() {
this.http.get<Weather>('/weather/lyon')
.subscribe(weather => this.weather = weather);
}
}
@Component({
template: `{{ weather$ | async | json }}`
})
export class WeatherComponent {
weather$ = this.http.get<Weather>('/weather/lyon');
}
Convoyr cache plugin
@convoyr/plugin-cache
Setup
Installing Convoyr and the plugin:
npm install @convoyr/core @convoyr/angular @convoyr/plugin-cache
Enable the cache plugin in the AppModule
:
import { ConvoyrModule } from '@convoyr/angular';
import { createCachePlugin } from '@convoyr/plugin-cache';
@NgModule({
imports: [
...
HttpClientModule,
ConvoyrModule.forRoot({
plugins: [createCachePlugin()],
}),
],
...
})
export class AppModule {}
How to know if the data comes from cache
addCacheMetadata
true
createCachePlugin({
addCacheMetadata: true
})
http.get('/weather/lyon')
.subscribe(data => console.log(data));
{
data: {
temperature: ...,
...
},
cacheMetadata: {
createdAt: '2020-01-01T00:00:00.000Z',
isFromCache: true
}
}
Convoyr's cache plugin is progressive
addCacheMetadata
shouldHandleRequest
import { and, matchOrigin, matchPath } from '@convoyr/core';
createCachePlugin({
shouldHandleRequest: and(
matchOrigin('marmicode.io'),
matchPath('/weather')
)
})
Storage
MemoryStorage
maxSize
createCachePlugin({
storage: new MemoryStorage({ maxSize: 2000 }), // 2000 requests
})
createCachePlugin({
storage: new MemoryStorage({ maxSize: '2 mb' }), // 2MB
})
🚀 Upcoming Features
Handle ReSTful APIs (e.g. /items
should populate /items/:itemId
so we can instantly show partial data from list views in detail views) Use IndexedDB as storage.