Skip to content

API and Fetch Example ​

Handler ​

ts
// server/api/tasks.ts
export default defineEventHandler(async (event) => {
  if (event.method === 'GET') {
    return [{ id: 1, title: 'Learn Resux', done: false }]
  }

  if (event.method === 'POST') {
    let body: unknown
    try {
      body = await readBody(event)
    } catch {
      return new Response('Invalid request body', { status: 400 })
    }

    if (
      !body ||
      typeof body !== 'object' ||
      Array.isArray(body) ||
      !('title' in body) ||
      typeof body.title !== 'string' ||
      !body.title.trim()
    ) {
      return new Response('Title is required', { status: 400 })
    }

    setHeader(event, 'cache-control', 'no-store')
    return { id: Date.now(), title: body.title.trim(), done: false }
  }

  return new Response('Method not allowed', { status: 405 })
})

Page ​

vue
<script setup lang="ts">
const tasks = await useFetch<Array<{ id: number; title: string; done: boolean }>>('/api/tasks')
const title = useState('new-task-title', () => '')
const saving = ref(false)
const submissionError = ref('')

async function addTask() {
  if (!title.value.trim() || saving.value) return

  submissionError.value = ''
  saving.value = true

  try {
    const created = await $fetch<{ id: number; title: string; done: boolean }>('/api/tasks', {
      method: 'POST',
      body: { title: title.value }
    })
    tasks.data.value = [...(tasks.data.value ?? []), created]
    title.value = ''
  } catch (error) {
    submissionError.value = error instanceof Error
      ? error.message
      : 'Unable to add the task'
  } finally {
    saving.value = false
  }
}
</script>

<template>
  <form @submit.prevent="addTask">
    <input v-model="title" />
    <button :disabled="saving">Add</button>
  </form>

  <p v-if="submissionError" role="alert">{{ submissionError }}</p>
  <p v-if="tasks.pending">Loading…</p>
  <p v-else-if="tasks.error">{{ tasks.error.message }}</p>
  <ul v-else>
    <li v-for="task in tasks.data" :key="task.id">{{ task.title }}</li>
  </ul>
</template>

useFetch returns refs for resource state. $fetch returns the parsed response directly.

Source-aligned documentation for the Resux resumable web framework.