Get Article List
Interface Information
- Endpoint:
/api/articles - Method:
GET - Content-Type:
application/json - Authentication Required: No
Request Parameters
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| page | number | No | 1 | Page number (starting from 1) |
| limit | number | No | 4 | Items per page (maximum 20) |
| featured | boolean | No | false | Whether to get only featured articles |
Request Examples
Get first page of articles
bash
curl -X GET "http://localhost:3000/api/articles?page=1&limit=4"Get featured articles
bash
curl -X GET "http://localhost:3000/api/articles?featured=true&limit=6"Get page 2 articles, 10 per page
bash
curl -X GET "http://localhost:3000/api/articles?page=2&limit=10"Response Example
Success Response
json
{
"success": true,
"data": [
{
"id": 1,
"title": "Nuxt 4 Full-Stack Development Guide",
"excerpt": "This article details how to build modern full-stack applications with Nuxt 4...",
"date": "2025-01-20T00:00:00.000Z",
"category": "Technical Sharing",
"cover": "https://example.com/covers/article1.jpg",
"comments": 5,
"views": 1200,
"slug": "nuxt-4-full-stack-development-guide-1"
},
{
"id": 2,
"title": "Vue 3 Composition API Best Practices",
"excerpt": "Deep understanding of Vue 3 Composition API usage techniques...",
"date": "2025-01-18T00:00:00.000Z",
"category": "Frontend Development",
"cover": "https://example.com/covers/article2.jpg",
"comments": 3,
"views": 850,
"slug": "vue-3-composition-api-best-practices-2"
}
],
"pagination": {
"page": 1,
"limit": 4,
"total": 50,
"pages": 13
}
}Response Field Descriptions
Article Object Fields
| Field Name | Type | Description |
|---|---|---|
| id | number | Article ID |
| title | string | Article title |
| excerpt | string | Article excerpt (first 100 characters) |
| date | string | Publication date (ISO 8601) |
| category | string | Category name |
| cover | string | null | Cover image URL |
| comments | number | Comment count (currently fixed at 0) |
| views | number | View count |
| slug | string | Article slug (for routing) |
Pagination Object Fields
| Field Name | Type | Description |
|---|---|---|
| page | number | Current page number |
| limit | number | Items per page |
| total | number | Total records |
| pages | number | Total pages |
Slug Generation Rules
Slug is generated from title and ID, format: {title-pinyin}-{id}
Example:
- Title: "Nuxt 4 Full-Stack Development Guide", ID: 1
- Slug: "nuxt-4-full-stack-development-guide-1"
Frontend Integration Examples
Using useFetch
vue
<script setup>
const route = useRoute()
const page = computed(() => route.query.page || 1)
const limit = computed(() => route.query.limit || 4)
const { data, pending, error, refresh } = await useFetch('/api/articles', {
query: { page, limit }
})
</script>
<template>
<div>
<div v-if="pending">Loading...</div>
<div v-else-if="error">Load failed</div>
<div v-else>
<!-- Article list -->
<article v-for="article in data.value.data" :key="article.id">
<img :src="article.cover" :alt="article.title" />
<h3>{{ article.title }}</h3>
<p>{{ article.excerpt }}</p>
<NuxtLink :to="`/articles/${article.slug}`">Read more</NuxtLink>
</article>
<!-- Pagination -->
<div class="pagination">
<NuxtLink
v-if="data.pagination.page > 1"
:to="`?page=${data.pagination.page - 1}`"
>
Previous
</NuxtLink>
<span>Page {{ data.pagination.page }} of {{ data.pagination.pages }}</span>
<NuxtLink
v-if="data.pagination.page < data.pagination.pages"
:to="`?page=${data.pagination.page + 1}`"
>
Next
</NuxtLink>
</div>
</div>
</div>
</template>Using Composable Function
typescript
// app/composables/useArticles.ts
export function useArticles() {
const articles = ref([])
const pagination = ref({
page: 1,
limit: 4,
total: 0,
pages: 0
})
const loading = ref(false)
const error = ref(null)
const fetchArticles = async (params = {}) => {
loading.value = true
error.value = null
try {
const response = await fetch(`/api/articles?${new URLSearchParams(params)}`)
const result = await response.json()
if (result.success) {
articles.value = result.data
pagination.value = result.pagination
} else {
throw new Error(result.message)
}
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
const loadPage = (page: number) => {
fetchArticles({ page, limit: pagination.value.limit })
}
return {
articles,
pagination,
loading,
error,
fetchArticles,
loadPage
}
}Usage Scenarios
1. Homepage Article List
javascript
const { data } = await useFetch('/api/articles', {
query: { featured: true, limit: 4 }
})2. Article Category Page
javascript
const { data } = await useFetch('/api/articles', {
query: { page, limit: 10 }
})3. Infinite Scroll Loading
javascript
const { articles, pagination, fetchArticles } = useArticles()
const loadMore = async () => {
if (pagination.value.page < pagination.value.pages) {
await fetchArticles({ page: pagination.value.page + 1 })
// Merge data
}
}
// Listen to scroll events
window.addEventListener('scroll', () => {
if (isBottom() && !loading.value) {
loadMore()
}
})Notes
- Only returns published articles: Articles with status
published - Pagination limits: Maximum 20 items per page, exceeding will be limited
- Time sorting: Default sorted by creation time descending
- Comment count: Currently fixed at 0, pending comment feature implementation