
nuxt-api-party

This module enables you to securely fetch data from any API by proxying the request in a Nuxt server route. Composable names are dynamic – given json-placeholder
set as the module option name
in your Nuxt config, the composables $jsonPlaceholder
and useJsonPlaceholderData
will be available globally.
Features
- 🪅 Dynamic composable names
- 🔒 Protected API credentials in the client
- 🪢 Token-based authentication built-in or bring your own headers
- 🍱 Feels just like
useFetch
- 🗃 Cached responses
- 🦾 Strongly typed
Setup
pnpm add -D nuxt-api-party
npm i -D nuxt-api-party
How It Works
Composables will initiate a POST request to the Nuxt server route /api/__api_party__
, which then fetches the actual data for a given route from your API and passes the response back to the template/client. This proxy behavior has the benefit of omitting CORS issues, since data is sent from server to server.
During server-side rendering, calls to the Nuxt server route will directly call the relevant function (emulating the request), saving an additional API call.
ℹ️ Responses are cached and hydrated to the client. Subsequent calls will return cached responses, saving duplicated requests.
Basic Usage
Add nuxt-api-party
to your Nuxt config and tell the module options the name of your API:
export default defineNuxtConfig({
modules: ['nuxt-api-party'],
apiParty: {
name: 'json-placeholder'
}
})
Set the following environment variables in your project's .env
file:
API_PARTY_BASE_URL=https://jsonplaceholder.typicode.com
If you were to call your API json-placeholder
, the generated composables are:
$jsonPlaceholder
– Returns the response data, similar to $fetch
useJsonPlaceholderData
– Returns multiple values similar to useFetch
Finally, fetch data from your API in your template:
<script setup lang="ts">
interface Post {
userId: number
id: number
title: string
body: string
}
// `data` will be typed as `Ref<Post | null>`
const { data, pending, refresh, error } = await useJsonPlaceholderData<Post>('posts/1')
</script>
<template>
<div>
<h1>{{ data?.title }}</h1>
<pre>{{ JSON.stringify(data, undefined, 2) }}</pre>
</div>
</template>
Module Options
Option | Type | Description |
---|
name
|
string
|
API name used for composables
For example, if you set it to foo , the composables will be called $foo and useFooData .
Default value: party
|
url
|
string
|
API base URL
For example, if you set it to foo , the composables will be called $foo and useFooData .
Default value: process.env.API_PARTY_BASE_URL
|
token
|
string
|
Optional API token for bearer authentication
You can set a custom header with the headers module option instead.
Default value: process.env.API_PARTY_TOKEN
|
headers
|
Record<string, string>
|
Custom headers sent with every request to the API
Add authorization headers if you want to use a custom authorization method.
Default value: {}
Example:
const username = 'foo'
const password = 'bar'
export default defineNuxtConfig({
apiParty: {
headers: {
'Custom-Api-Header': 'foo',
'Authorization': `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
}
}
})
|
Composables
Customize your API's composable names with the name
in your Nuxt config module option. Given it is set to json-placeholder
, the composables $jsonPlaceholder
and useJsonPlaceholderData
will be available globally.
ℹ️ The headings of the following sections aren't available as-is. As an example, the module option name
is set to party
.
$party
(Respectively Camel-Cased API Name)
Returns the API response data.
Type Declarations
function $party<T = any>(
path: string,
opts: ApiFetchOptions = {},
): Promise<T>
type ApiFetchOptions = Pick<
FetchOptions,
'onRequest' | 'onRequestError' | 'onResponse' | 'onResponseError' | 'headers'
>
Example
<script setup lang="ts">
const data = await $party(
'posts/1',
{
async onRequest({ request }) {
console.log(request)
},
async onResponse({ response }) {
console.log(response)
},
async onRequestError({ error }) {
console.log(error)
},
async onResponseError({ error }) {
console.log(error)
},
}
)
</script>
<template>
<div>
<h1>{{ data?.title }}</h1>
</div>
</template>
usePartyData
(Respectively Pascal-Cased API Name)
Return values:
- data: the response of the API request
- pending: a boolean indicating whether the data is still being fetched
- refresh: a function that can be used to refresh the data returned by the handler function
- error: an error object if the data fetching failed
By default, Nuxt waits until a refresh
is finished before it can be executed again. Passing true
as parameter skips that wait.
Type Declarations
function usePartyData<T = any>(
path: MaybeComputedRef<string>,
opts: UseApiDataOptions<T> = {},
): AsyncData<T, FetchError | null | true>
type UseApiDataOptions<T> = Pick<
AsyncDataOptions<T>,
| 'server'
| 'lazy'
| 'default'
| 'watch'
| 'immediate'
> & Pick<
FetchOptions,
| 'onRequest'
| 'onRequestError'
| 'onResponse'
| 'onResponseError'
| 'headers'
>
The composable infers most of the useAsyncData
options.
Example
<script setup lang="ts">
const { data, pending, error, refresh } = await usePartyData('posts/1')
</script>
<template>
<div>
<h1>{{ data?.result?.title }}</h1>
<button @click="refresh()">
Refresh
</button>
</div>
</template>
💻 Development
- Clone this repository
- Enable Corepack using
corepack enable
- Install dependencies using
pnpm install
- Run
pnpm run dev:prepare
- Start development server using
pnpm run dev
Special Thanks
License
MIT License © 2022 Johann Schopplich