Skip to content

Feature Cache Strategy #56

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import ApiService from '@/services/api.service';
import ApiService from '@/repositories/api.repository';

import TokenService from '@/services/token.service';
import ThemeService from '@/services/theme.service';
import LanguageService from '@/services/language.service';

import AuthenticateUser from '@/services/middleware/AuthenticateUser';
import AuthenticateUser from '@/repositories/middleware/AuthenticateUser';

import HttpHeader from '@/enums/HttpHeader';
import MimeType from '@/enums/MimeType';
import HttpHeader from '@/enums/HttpHeader';

ApiService.setHeader(HttpHeader.CONTENT_TYPE, MimeType.APPLICATION_JSON);
ApiService.addResponseMiddleware(AuthenticateUser);
Expand Down
8 changes: 4 additions & 4 deletions src/composables/todo.composable.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ref, computed } from 'vue';

// Service
import TodoService from '@/services/todo.service';
import TodoRepository from '@/repositories/todo.repository';

// Composables
import { useLoading } from '@/composables/loading.composable';
Expand All @@ -22,7 +22,7 @@ export function useFetchTodos() {
function fetchTodos(config) {
startLoading();

return TodoService.getAll(config)
return TodoRepository.getAll(config)
.then(function (response) {
todos.value = response.data;
return response;
Expand All @@ -40,15 +40,15 @@ export function useFetchTodos() {
};
}

export function useFetchTodo(initialValue = TodoService.getDefault()) {
export function useFetchTodo(initialValue = TodoRepository.getDefault()) {
const { isLoading, startLoading, endLoading } = useLoading();

const todo = ref(initialValue);

function fetchTodoById(id) {
startLoading();

return TodoService.getOneById(id)
return TodoRepository.getOneById(id)
.then(function (response) {
todo.value = response.data;
return response;
Expand Down
8 changes: 4 additions & 4 deletions src/composables/user.composable.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ref, computed } from 'vue';

// Service
import UserService from '@/services/user.service';
import UserRepository from '@/repositories/user.repository';

// Composables
import { useLoading } from '@/composables/loading.composable';
Expand All @@ -19,7 +19,7 @@ export function useFetchUsers() {
function fetchUsers() {
startLoading();

return UserService.getAll()
return UserRepository.getAll()
.then(function (response) {
users.value = response.data;
return response;
Expand All @@ -37,15 +37,15 @@ export function useFetchUsers() {
};
}

export function useFetchUser(initialValue = UserService.getDefault()) {
export function useFetchUser(initialValue = UserRepository.getDefault()) {
const { isLoading, startLoading, endLoading } = useLoading();

const user = ref(initialValue);

function fetchUserById(id) {
startLoading();

return UserService.getOneById(id)
return UserRepository.getOneById(id)
.then(function (response) {
user.value = response.data;
return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const instance = axios.create({
timeout: import.meta.env.VITE_API_TIMEOUT
});

class ApiService {
class ApiRepository {
/**
* Set header for all or specific http method
*
Expand Down Expand Up @@ -142,4 +142,4 @@ class ApiService {
}
}

export default ApiService;
export default ApiRepository;
15 changes: 15 additions & 0 deletions src/repositories/base.repository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class BaseRepository {
/**
* Repository url
*
* @throws {Error}
* @returns {String}
*/
get URL() {
throw new Error(
'You have to implement the static method "URL", for each class that extend BaseRepositories!'
);
}
}

export default BaseRepository;
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
import ApiService from './api.service';

class CrudService {
/**
* Service url
*
* @throws {Error}
* @returns {String}
*/
static get URL() {
throw new Error(
'You have to implement the static method "URL", for each class that extend CrudServices!'
);
}
import ApiRepository from './api.repository';
import BaseRepository from './base.repository';

class CrudRepository extends BaseRepository {
/**
* Get items
*
* @param {AxiosRequestConfig} [config]
* @returns {Promise<AxiosResponse>}
*/
static getAll(config) {
return ApiService.get(this.URL, config);
getAll(config) {
return ApiRepository.get(this.URL, config);
}

/**
Expand All @@ -30,8 +19,8 @@ class CrudService {
* @param {AxiosRequestConfig} [config]
* @returns {Promise<AxiosResponse>}
*/
static getOneById(id, config) {
return ApiService.get(`${this.URL}/${id}`, config);
getOneById(id, config) {
return ApiRepository.get(`${this.URL}/${id}`, config);
}

/**
Expand All @@ -41,8 +30,8 @@ class CrudService {
* @param {AxiosRequestConfig} [config]
* @returns {Promise<AxiosResponse>}
*/
static create(data, config) {
return ApiService.post(`${this.URL}/create`, data, config);
create(data, config) {
return ApiRepository.post(`${this.URL}/create`, data, config);
}

/**
Expand All @@ -53,8 +42,8 @@ class CrudService {
* @param {AxiosRequestConfig} [config]
* @returns {Promise<AxiosResponse>}
*/
static update(id, data, config) {
return ApiService.post(`${this.URL}/${id}/update`, data, config);
update(id, data, config) {
return ApiRepository.post(`${this.URL}/${id}/update`, data, config);
}

/**
Expand All @@ -65,9 +54,9 @@ class CrudService {
* @param {AxiosRequestConfig} [config]
* @returns {Promise<AxiosResponse>}
*/
static delete(id, data, config) {
return ApiService.post(`${this.URL}/${id}/delete`, data, config);
delete(id, data, config) {
return ApiRepository.post(`${this.URL}/${id}/delete`, data, config);
}
}

export default CrudService;
export default CrudRepository;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import AuthenticationService from '@/services/authentication.service';
import router from '@/router/index';

import router from '@/router/index';
import HttpStatusCode from '@/enums/HttpStatusCode';

/**
Expand Down
96 changes: 96 additions & 0 deletions src/repositories/strategy/BaseStrategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Utils
import { isEmptyObject } from '@/utils';

// Services
import LocalStorageService from '@/services/local-storage.service';

const Default = {
ttl: 60_000,
driver: LocalStorageService,
cacheTag: 'global'
};

class BaseStrategy {
/**
* @type {Object}
* @private
*/
_cache;

/**
* @type {Number}
* @private
*/
_ttl;

/**
* @type {Object}
* @private
*/
_driver;

/**
* @type {String}
* @private
*/
_cacheTag;

/**
* @param {Object} config
* @param {Number} [config.ttl]
* @param {Object} [config.driver]
* @param {String} [config.cacheTag]
*/
constructor(config) {
// Todo => checking the type of configurations
const { ttl, driver, cacheTag } = {
...Default,
...(typeof config === 'object' ? config : {})
};

this._ttl = ttl;
this._driver = driver;
this._cacheTag = cacheTag;

this._cache = this._initializeCache();
}

// Private

/**
* Get cache bu tag
*
* @private
* @returns {*|{}}
*/
_initializeCache() {
return this._driver.get(this._cacheTag) ?? {};
}

/**
* Save cache by tag
*
* @private
* @returns void
*/
_saveCache() {
if (isEmptyObject(this._cache)) {
this._clearCache();
return;
}

this._driver.set(this._cacheTag, this._cache);
}

/**
* Clear cache by tag
*
* @private
* @returns void
*/
_clearCache() {
this._driver.delete(this._cacheTag);
}
}

export default BaseStrategy;
Loading