This guide helps you transition from the old individual endpoint structure to the new RESTful API structure.
The API has been completely restructured to follow RESTful conventions with proper TypeScript typing. All endpoints are now grouped by resource type and use standard HTTP methods.
- Create:
POST /api/alternatives - List:
GET /api/alternatives - Get Single:
GET /api/alternatives/:id - Update:
PATCH /api/alternatives/:id - Delete:
DELETE /api/alternatives/:id
- Create:
POST /api/categories - List:
GET /api/categories - Get Single:
GET /api/categories/:id - Update:
PATCH /api/categories/:id - Delete:
DELETE /api/categories/:id
- Create:
POST /api/tools - List:
GET /api/tools - Get Single:
GET /api/tools/:id - Get by Slug:
GET /api/tools/slug/:slug - Update:
PATCH /api/tools/:id - Delete:
DELETE /api/tools/:id
- Create:
POST /api/images - List:
GET /api/images - Get Single:
GET /api/images/:id - Update:
PATCH /api/images/:id - Delete:
DELETE /api/images/:id
The composables have been updated to use the new API structure. Here are the key changes:
// CREATE Alternative
const createAlternative = async (payload) => {
return await useFetch("/api/create-alternative", {
method: "POST",
body: payload,
});
};
// UPDATE Alternative
const updateAlternative = async (id, payload) => {
return await useFetch(`/api/update-alternative?id=${id}`, {
method: "PATCH",
body: payload,
});
};
// DELETE Alternative
const deleteAlternative = async (id) => {
return await useFetch(`/api/delete-alternative?id=${id}`, {
method: "DELETE",
});
};
// GET Alternatives with pagination and search
const getAlternatives = async ({ page = 1, limit = 20, q = "" } = {}) => {
const params = new URLSearchParams();
params.append("page", page);
params.append("limit", limit);
if (q) params.append("q", q);
return await useFetch(`/api/get-alternatives?${params.toString()}`);
};// CREATE Alternative
const createAlternative = async (payload: CreateAlternativeInput) => {
return await useFetch("/api/alternatives", {
method: "POST",
body: payload,
});
};
// UPDATE Alternative
const updateAlternative = async (id: string, payload: UpdateAlternativeInput) => {
return await useFetch(`/api/alternatives/${id}`, {
method: "PATCH",
body: payload,
});
};
// DELETE Alternative
const deleteAlternative = async (id: string) => {
return await useFetch(`/api/alternatives/${id}`, {
method: "DELETE",
});
};
// GET Alternatives with pagination and search
const getAlternatives = async ({ page = 1, limit = 20, q = "" }: { page?: number; limit?: number; q?: string } = {}) => {
const params = new URLSearchParams();
params.append("page", page.toString());
params.append("limit", limit.toString());
if (q) params.append("q", q);
return await useFetch(`/api/alternatives?${params.toString()}`);
};Update your components to use the new composable functions. The main changes are:
-
Import the updated composables:
import { useAlternativesApi } from "@/composables/useAlternativesApi";
-
Update API call patterns:
- Old:
createAlternative(payload) - New:
createAlternative(payload)
- Old:
-
Handle the new response format:
- Old response:
{ data: any } - New response:
{ success: boolean, data: any, message?: string }
- Old response:
The new API uses standardized error responses:
// Example error handling
const { data, error } = await getAlternatives({ page: 1, limit: 10 });
if (error.value) {
console.error("API Error:", error.value);
// Handle error (show toast, etc.)
} else if (data.value && !data.value.success) {
console.error("API Error:", data.value.message);
// Handle error (show toast, etc.)
}The tools API now has an additional endpoint for getting tools by slug:
const getToolBySlug = async (slug: string) => {
return await useFetch(`/api/tools/slug/${slug}`);
};The image upload endpoint (/api/upload-image) remains unchanged as it's a special case.
All composables now have proper TypeScript typing. You can import the types from server/types:
import type {
Alternative,
Category,
Tool,
Image,
CreateAlternativeInput,
UpdateAlternativeInput,
// ... other types
} from "@/types";Before fully migrating, test the new API endpoints:
- Test each endpoint with tools like Postman or cURL
- Verify responses match the expected format
- Check error handling by sending invalid data
- Test pagination with different page sizes and search queries
After verifying everything works correctly:
- Remove old individual endpoint files (already done)
- Update any remaining references to old endpoints
- Verify all frontend functionality works as expected