Configuration
Agrume is designed to be as simple as possible. It doesn’t need any configuration to work. However, you can configure it to suit your needs.
prefix
By default, Agrume will prefix all your routes with /api
. You can change this prefix by passing the prefix
option to the plugin:
// ...
export default defineConfig({
plugins: [
agrume({
prefix: '/my-api/'
})
// ...
]
})
baseUrl
By default, Agrume will make requests to the same host as the frontend. However, you can change this by passing the baseUrl
option to the plugin:
// ...
export default defineConfig({
plugins: [
agrume({
baseUrl: 'http://localhost:3000/'
})
// ...
]
})
Note
It can be useful if you host your frontend and backend on different servers or different processes.
Note
The difference between prefix
and baseUrl
is that prefix
will impact both the transformation step (the frontend) and the registration step (the backend), while baseUrl
will only impact the transformation step (the frontend).
useMiddleware
By default, Agrume will use the Vite server to serve your API. However, you can use your own server by passing the useMiddleware
option to the plugin:
// ...
import { server } from './server'
export default defineConfig({
plugins: [
agrume({
useMiddleware: server.use.bind(server),
})
// ...
]
})
The useMiddleware
option takes a function that takes a Connect-like middleware as an argument. Here is an example of a Connect-like server:
import { createServer } from "node:http"
import connect from "connect"
const app = connect()
const server = createServer(app)
server.listen(3000)
export { app as server }
Many backend frameworks can use Connect-like middleware. For example, Express can use Connect-like middleware. You can use it as a server:
import express from 'express'
const app = express()
const server = app.listen(3000)
export { app as server }
But please, don’t use Express. See “Why you should drop ExpressJS” by Romain Lanz.
logger
By default, Agrume does not log anything. However, you can pass a logger to the plugin to log the requests:
// ...
export default defineConfig({
plugins: [
agrume({
logger: {
info: console.info,
error: console.error,
}
})
// ...
]
})
You can use fs.writeFileSync
instead of console.log
to log the requests to a file.
// ...
export default defineConfig({
plugins: [
agrume({
logger: {
info: (...args) => fs.writeFileSync('info.log', args.join(' ') + '\n', { flag: 'a' }),
error: (...args) => fs.writeFileSync('error.log', args.join(' ') + '\n', { flag: 'a' }),
}
})
// ...
]
})
tunnel
Agrume has built-in support for tunnels. You can opt-in to use a tunnel by passing the tunnel
option to the plugin:
// ...
export default defineConfig({
plugins: [
agrume({
tunnel: { type: 'Bore', connectionArgs: {} }
})
// ...
]
})
Note
You may want to use the Agrume CLI to start the tunnel easily. See the CLI section.
ngrok
Ngrok is the most popular of all the options. However, it have some prerequisites:
- Create an account on ngrok.com.
- Go to the auth token page and copy your auth token.
- Set the
NGROK_AUTHTOKEN
environment variable to your auth token.
echo "export NGROK_AUTHTOKEN=your-auth-token" >> ~/.zshrc # or ~/.bashrc or any other shell configuration file
- Create a free static subdomain on ngrok.com.
- Set the
ngrokDomain
option to your subdomain.
1. with the CLI:
agrume --tunnel ngrok --ngrok-domain your-subdomain
2. with the plugin:
// ...
export default defineConfig({
// ...
tunnel: {
type: 'Ngrok',
connectionArgs: {
accessToken: process.env.NGROK_AUTHTOKEN, // This is optional, it will use the NGROK_AUTHTOKEN environment variable by default.
},
tunnelDomain: 'your-ngrok-domain',
}
})
pinggy
Pinggy is a stable and cheaper alternative to Ngrok.
- Create an account on pinggy.io.
- Go to the subscriptions page and upgrade to a paid plan (3$/month).
- Go to the subdomains page and create a static subdomain.
- Set the
pinggySubdomain
andpinggyToken
options to your subdomain and your token.
1. with the CLI:
agrume --tunnel pinggy --pinggy-subdomain your-subdomain --pinggy-token your-token
Note
Ideally, you should set the PINGGY_TOKEN
environment variable to your token and use this variable in the command.
2. with the plugin:
// ...
export default defineConfig({
// ...
tunnel: {
type: 'Pinggy',
connectionArgs: {
accessToken: process.env.PINGGY_TOKEN,
},
tunnelSubdomain: 'your-subdomain',
},
})
bore
Bore is a free and open-source tunnel. However, it doesn’t support HTTPS and works with ports (anybody can reserve a port, so the determined URL can be taken by someone else).
- Install the
bore
CLI (read the installation instructions). - Use
bore
as the tunnel type.
localtunnel
Localtunnel is a free and open-source tunnel. However, the service is not very stable. It doesn’t need any installation.
- Use
localtunnel
as the tunnel type.
getClient
By default, Agrume will use the client written at packages/client/src/get-client.ts
. However, you can pass your own client to the plugin:
export default defineConfig({
plugins: [
agrume({
getClient: (requestOptions) => {
// Your client
}
})
// ...
]
})
If you want to modify the type of the client compared to the default client, you can do as follows:
// ...
import type { createRoute } from 'agrume'
import type { AnyRoute, RequestOptions, RouteTypes } from '@agrume/types'
function getClient<RT extends RouteTypes<AnyRoute>>(
requestOptions: RequestOptions,
_?: RT
) {
type Parameters = createRoute.Helpers.InferRouteTypes.Parameters<RT> // you can modify the parameters your client will take (for example, add a token parameter)
// For example, if you want to add a token parameter:
// type Parameters = [...createRoute.Helpers.InferRouteTypes.Parameters<RT>, { token: string }]
type ReturnType = createRoute.Helpers.InferRouteTypes.ReturnType<RT> // you can modify the return type of your client
return async (...parameters: Parameters): Promise<ReturnType> => {
// Your client
}
}
export default defineConfig({
plugins: [
agrume({
getClient,
}),
// ...
]
})
declare module '@agrume/types' {
export interface CustomClient<R> {
getClient: typeof getClient<RouteTypes<R>>
}
}
Important
Make sure that the declare module
is in a file included in your tsconfig.json
. If you don’t want to include your build tool’s configuration file, you can put the getClient
and the declare module
in a separate file that is included in your tsconfig.json
.