Query
A query in Alette Signal is a request blueprint provided by the "core" plugin and is preconfigured for sending GET
HTTP requests.
Preconfigured query behaviour
- Uses the
GET
HTTP method to send a request to the server. - Uses the
runOnMount()
middleware to start request execution immediately when the request is mounted. - Retries the request once if the thrown error contains these HTTP statuses:
401
,408
,409
,419
,425
,429
,500
,502
,503
,504
. - Throws a
RequestFailedError
if the response returned from the server does not have a2xx
HTTP status.
WARNING
Queries are designed for getting server data without it on your backend. If you want to modify server data, use mutation or custom.
Using query blueprint
To use the query request blueprint, extract it from the Alette Signal "core" plugin:
// ./src/api/base.ts
import { client, activatePlugins, coreApiPlugin } from "@alette/signal";
const core = coreApiPlugin();
export const api = client(
/* ... */
activatePlugins(core.plugin),
);
export const { query } = core.use();
Now you can add middleware and execute requests:
// ./src/api/posts.ts
import {
input,
output,
debounce,
map,
path,
queryParams
} from '@alette/signal';
import { query } from "./base";
import * as z from 'zod';
export const Post = z.object({ /*...*/ });
export const Posts = Post.array();
export const PostStatus = z.enum(['draft', 'published'])
export const searchPosts = query(
input(
z.object({
search: z.string().default(''),
status: PostStatus.default('published')
})
),
output(Posts),
path(({ args: { status } }) => `/posts/search/${status}`),
queryParams(({ args: { search } }) => ({ search }))
);
export const getPostsForSelect = searchPosts.with(
debounce(300),
map((posts) =>
posts.map(({ title, id }) => ({ label: title, value: id }))
)
);
// Later...
await getPostsForSelect.execute({ search: 'Alette Signal' })
// or
await searchPosts.execute({ search: 'Alette Signal' })
Using query with UI frameworks
To use the query request blueprint with UI frameworks, refer to the Alette Signal framework integration guides:
Disabling mounted execution
To disable query execution on mount, use the runOnMount()
middleware:
const { execute } = getPostsForSelect
.with(runOnMount(false))
.mount()
// Later...
execute()
INFO
A query that is not executed on mount is called "lazy".
Query cancellation
To cancel an in-flight query request, use cancel()
:
const { cancel } = getPostsForSelect.mount()
// Later...
cancel()
WARNING
Request cancellation does not throw errors.
Query abortion
To abort an in-flight query request, call the .abort()
method on the AbortController passed to the abortedBy()
middleware:
const abortController = new AbortController();
getPostsForSelect
.with(abortedBy(abortController))
.execute();
// Later...
abortController.abort()
DANGER
Request abortion throws a RequestAbortedError
.
Query limitations
- Cannot send request body.
- Cannot track body upload progress using the
tapUploadProgress()
middleware. - Cannot override used HTTP method using the
method()
middleware. - Cannot implement custom request execution logic using the
factory()
middleware. - Cannot add new thrown error types using the
throws()
middleware. - Expects a response in
JSON
format back from the server.