This guide will help you set up and start using @qualisero/openapi-endpoint in your Vue project.
- Vue 3.3 or higher
- TanStack Vue Query 5.90 or higher
- Axios 1.12 or higher
- An OpenAPI specification (JSON or YAML) for your API
npm install @qualisero/openapi-endpointOr with yarn:
yarn add @qualisero/openapi-endpointThis package includes a CLI tool to generate TypeScript types and operation definitions from your OpenAPI specification.
npx @qualisero/openapi-endpoint ./api/openapi.json ./src/generatednpx @qualisero/openapi-endpoint https://api.example.com/openapi.json ./src/apiThis will generate three files:
openapi-types.ts- TypeScript type definitions for your APIapi-operations.ts- Operation definitions combining metadata and typesapi-enums.ts- Type-safe enum constants from your API schema
Create an axios instance with your API configuration:
// api/axios.ts
import axios from 'axios'
export const axiosInstance = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
})
// Add authentication interceptor if needed
axiosInstance.interceptors.request.use((config) => {
const token = localStorage.getItem('authToken')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})Create a typed API client using the generated createApiClient factory:
// api/init.ts
import { createApiClient } from '@qualisero/openapi-endpoint'
import { axiosInstance } from './axios'
const api = createApiClient(axiosInstance)
export { api }If you need to customize the TanStack Query client, you can provide your own:
// api/init.ts
import { createApiClient } from '@qualisero/openapi-endpoint'
import { QueryClient } from '@tanstack/vue-query'
import { axiosInstance } from './axios'
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes
retry: 3,
},
mutations: {
retry: 1,
},
},
})
const api = createApiClient(axiosInstance, queryClient)
export { api }<script setup lang="ts">
import { api } from './api/init'
const { data: pets, isLoading, error } = api.listPets.useQuery()
if (error.value) {
console.error('Failed to load pets:', error.value)
}
</script>
<template>
<div v-if="isLoading">Loading pets...</div>
<div v-else-if="error">Error loading pets</div>
<ul v-else>
<li v-for="pet in pets" :key="pet.id">{{ pet.name }}</li>
</ul>
</template><script setup lang="ts">
import { ref } from 'vue'
import { api } from './api/init'
const name = ref('')
const createPet = api.createPet.useMutation({
onSuccess: () => {
console.log('Pet created!')
name.value = ''
},
onError: (error) => {
console.error('Failed to create pet:', error)
},
})
const handleSubmit = async () => {
await createPet.mutateAsync({ data: { name: name.value } })
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<input v-model="name" placeholder="Pet name" />
<button type="submit" :disabled="createPet.isPending">
{{ createPet.isPending ? 'Creating...' : 'Create Pet' }}
</button>
</form>
</template>The CLI generates type-safe enum constants from your OpenAPI spec:
<script setup lang="ts">
import { api } from './api/init'
import { PetStatus } from './api/generated/api-enums'
// Use enum constants for intellisense and typo safety
const { data: availablePets } = api.listPets.useQuery({
queryParams: { status: PetStatus.Available },
})
const createPet = api.createPet.useMutation()
const handleSubmit = async () => {
await createPet.mutateAsync({
data: { name: 'Fluffy', status: PetStatus.Pending },
})
}
</script>- Queries - Learn about using queries for GET operations
- Mutations - Learn about mutations for POST/PUT/PATCH/DELETE operations
- Reactive Parameters - Learn about reactive query and path parameters
- Cache Management - Learn about automatic and manual cache control