N
Nuxt3mo ago
pook1574

Repository Pattern implementation attempt

import type { NitroFetchOptions } from "nitropack";
import type { IPaginationResponse } from "@/types/IPaginationResponse";
import type { DjangoPaginationQueryParams } from "@/types/DjangoPaginationQueryParams";
export abstract class BaseRepository<T> {
protected abstract baseUrl: string;
protected defaultFetch = $fetch; // Using Nuxt's global $fetch
async getAllPaginated(
queryParams: DjangoPaginationQueryParams,
fetcher = this.defaultFetch
): Promise<IPaginationResponse<T>> {
const options: NitroFetchOptions<"get"> = {
method: "get", // Using GET method without body
};
const queryString = new URLSearchParams(
Object.entries(queryParams).reduce((acc, [key, value]) => {
acc[key] = String(value);
return acc;
}, {} as Record<string, string>)
).toString();
const response = await fetcher<IPaginationResponse<T>>(
`${this.baseUrl}?${queryString}`, // Append query string to base URL
options
);
return response;
}

async create(payload: T, fetcher = this.defaultFetch): Promise<T> {
const data = await fetcher<T>(this.baseUrl, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
},
});
return data;
}

async update(
id: number,
payload: T,
fetcher = this.defaultFetch
): Promise<T> {
const data = await fetcher<T>(`${this.baseUrl}/${id}`, {
method: "PUT",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
},
});
return data;
}
async save(
entity: T & { id?: number },
fetcher = this.defaultFetch
): Promise<T> {
if (entity.id) {
return this.update(entity.id, entity, fetcher);
} else {
return this.create(entity, fetcher);
}
}
}
import type { NitroFetchOptions } from "nitropack";
import type { IPaginationResponse } from "@/types/IPaginationResponse";
import type { DjangoPaginationQueryParams } from "@/types/DjangoPaginationQueryParams";
export abstract class BaseRepository<T> {
protected abstract baseUrl: string;
protected defaultFetch = $fetch; // Using Nuxt's global $fetch
async getAllPaginated(
queryParams: DjangoPaginationQueryParams,
fetcher = this.defaultFetch
): Promise<IPaginationResponse<T>> {
const options: NitroFetchOptions<"get"> = {
method: "get", // Using GET method without body
};
const queryString = new URLSearchParams(
Object.entries(queryParams).reduce((acc, [key, value]) => {
acc[key] = String(value);
return acc;
}, {} as Record<string, string>)
).toString();
const response = await fetcher<IPaginationResponse<T>>(
`${this.baseUrl}?${queryString}`, // Append query string to base URL
options
);
return response;
}

async create(payload: T, fetcher = this.defaultFetch): Promise<T> {
const data = await fetcher<T>(this.baseUrl, {
method: "POST",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
},
});
return data;
}

async update(
id: number,
payload: T,
fetcher = this.defaultFetch
): Promise<T> {
const data = await fetcher<T>(`${this.baseUrl}/${id}`, {
method: "PUT",
body: JSON.stringify(payload),
headers: {
"Content-Type": "application/json",
},
});
return data;
}
async save(
entity: T & { id?: number },
fetcher = this.defaultFetch
): Promise<T> {
if (entity.id) {
return this.update(entity.id, entity, fetcher);
} else {
return this.create(entity, fetcher);
}
}
}
3 Replies
pook1574
pook1574OP3mo ago
I read a few articles and watched some videos... and used the heck out chat GPT and this is what I came up with for a repository pattern base class, a class that endpoint specific classes can inherit ... like-this

import type { IPortalCard } from "@/types/portal/IPortalCard";
import { BaseRepository } from "@/repository/BaseRepository";
import { SERVER } from "@/repository/ApiEnum";
import FindServer from "@/repository/BaseURL";

export class PortalRepository extends BaseRepository<IPortalCard> {
protected baseUrl = `${FindServer.getApiUrl(SERVER.DJANGO)}portal-cards`;
}

import type { IPortalCard } from "@/types/portal/IPortalCard";
import { BaseRepository } from "@/repository/BaseRepository";
import { SERVER } from "@/repository/ApiEnum";
import FindServer from "@/repository/BaseURL";

export class PortalRepository extends BaseRepository<IPortalCard> {
protected baseUrl = `${FindServer.getApiUrl(SERVER.DJANGO)}portal-cards`;
}
I was hoping if someone had experience implementing a repository pattern in nuxt might give me some feedback on this before I run with it... see any future set backs with using this? I also made a plugin like this
import { PortalRepository } from "@/repository/modules/portal/PortalRepository";

export default defineNuxtPlugin(() => {
const api = {
portal: new PortalRepository(),
// Add more repositories here as needed
};
return {
provide: {
api,
},
};
});

import { PortalRepository } from "@/repository/modules/portal/PortalRepository";

export default defineNuxtPlugin(() => {
const api = {
portal: new PortalRepository(),
// Add more repositories here as needed
};
return {
provide: {
api,
},
};
});

If any of you have a more simple solution I would love to hear it
manniL
manniL3mo ago
Alexander Lichter
YouTube
Custom $fetch and Repository Pattern in Nuxt 3
💻 The repository pattern is a popular way to abstract your API calls away and provide a descriptive way to retrieve or send data. But how would you implement it in Nuxt? And should you use composables or $fetch for it? This video will give answers to all the questions! Key points: 🎛️ Implementing the repository pattern in Nuxt 🔛 Creating our ow...
pook1574
pook1574OP3mo ago
I did, It was a great video. I used a lot of the logic in this video, along with a couple of articles like - https://medium.com/@luizzappa/nuxt-3-repository-pattern-organising-and-managing-your-calls-to-apis-with-typescript-acd563a4e046
Medium
Nuxt 3 | Repository pattern: organising and managing your calls to ...
In Nuxt 2 the use of axios was straightforward and allowed a good management of API calls. When I started to develop with Nuxt 3 I found it…
Want results from more Discord servers?
Add your server