Текущая реализация graphql/api/public.ts
// Сейчас мы используем cache из @solidjs/router
export const loadTopics = () =>
cache(async () => {
const resp = await defaultClient.query(loadTopicsQuery, {}).toPromise()
return resp?.data?.get_topics_all as Topic[]
}, 'topics')
export const loadShouts = (args: QueryLoad_Shouts_ByArgs) => {
const page = `${options?.offset || 0}-${(options?.limit || 0) + (options?.offset || 0)}`
const filter = new URLSearchParams(options?.filters as Record<string, string>)
return cache(async () => {
const resp = await defaultClient.query(loadShoutsByQuery, args).toPromise()
return resp?.data?.load_shouts_by as Shout[]
}, `shouts-${filter}-${page}`)
}
По словам Райана Карниато:
cache
был временным решением- Не работает с SSR и гидрацией
- Не интегрируется с новой системой ресурсов
// Было
export const loadTopics = () =>
cache(async () => {
const resp = await defaultClient.query(loadTopicsQuery, {}).toPromise()
return resp?.data?.get_topics_all
}, 'topics')
// Стало
export const useTopics = () => {
return createResource(async () => {
const resp = await defaultClient.query(loadTopicsQuery, {}).toPromise()
return resp?.data?.get_topics_all
})
}
// Было
export const loadShouts = (args: QueryLoad_Shouts_ByArgs) => {
const key = `shouts-${JSON.stringify(args)}`
return cache(async () => {
const resp = await defaultClient.query(loadShoutsByQuery, args).toPromise()
return resp?.data?.load_shouts_by
}, key)
}
// Стало
export const useShouts = (args: QueryLoad_Shouts_ByArgs) => {
return createResource(
() => args, // Зависимость - при изменении args ресурс перезагрузится
async (currentArgs) => {
const resp = await defaultClient.query(loadShoutsByQuery, currentArgs).toPromise()
return resp?.data?.load_shouts_by
}
)
}
// Было
export const loadReactions = (options: QueryLoad_Reactions_ByArgs, client?: Client) => {
const key = `reactions-${JSON.stringify(options)}`
return cache(async () => {
const resp = await (client || defaultClient)
.query(loadReactionsByQuery, options)
.toPromise()
return resp?.data?.load_reactions_by
}, key)
}
// Стало
export const useReactions = (options: QueryLoad_Reactions_ByArgs) => {
const session = useSession()
return createResource(
() => [options, session.client], // Зависимости
async ([currentOptions, client]) => {
const resp = await (client || defaultClient)
.query(loadReactionsByQuery, currentOptions)
.toPromise()
return resp?.data?.load_reactions_by
}
)
}
FeedView components/Views/FeedView.tsx
// Было
const feed = loadShouts({ options })
// Стало
const [feed] = useShouts({ options })
return (
<Show when={!feed.loading} fallback={<Loading />}>
<For each={feed()}>{shout =>
<ArticleCard shout={shout} />
}</For>
</Show>
)
TopicView components/Views/TopicView.tsx
// Было
const topicData = loadTopics()
// Стало
const [topics] = useTopics()
const topicData = createMemo(() =>
topics()?.find(t => t.slug === props.slug)
)
-
Автоматическое отслеживание зависимостей
- Ресурс перезагружается при изменении параметров
- Нет необходимости в ручной инвалидации кэша
- Прозрачная интеграция с реактивностью
-
Лучшая типизация
- TypeScript понимает типы данных
- Автодополнение в IDE
- Проверка ошибок при компиляции
-
Готовность к SSR
- Работает с SolidStart из коробки
- Поддержка streaming SSR
- Корректная гидрация
-
Этап 1: Базовые запросы
- Заменить простые cache на createResource
- Обновить компоненты для работы с ресурсами
- Проверить работу загрузки и ошибок
-
Этап 2: Параметризованные запросы
- Добавить отслеживание зависимостей
- Обновить логику пагинации
- Проверить обновление при смене параметров
-
Этап 3: Авторизованные запросы
- Интегрировать с системой сессий
- Добавить обработку токенов
- Проверить работу с разными клиентами