Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 52 additions & 9 deletions apps/website/docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export default withMermaid(
'/tutorial': [
{
text: 'Thorough Tutorial',
collapsed: false,
collapsed: true,
items: [
{ text: 'Get started', link: '/tutorial/' },
{ text: 'Installation', link: '/tutorial/install' },
Expand Down Expand Up @@ -143,21 +143,64 @@ export default withMermaid(
],
},
{
text: 'Solid',
text: 'With UI-libs',
collapsed: true,
items: [
{ text: 'Get started', link: '/tutorial/solid/' },
{ text: 'Suspense', link: '/tutorial/solid/suspense' },
{ text: 'SSR and Testing', link: '/tutorial/solid/scope' },
{
text: 'Solid',
collapsed: true,
items: [
{ text: 'Get started', link: '/tutorial/solid/' },
{ text: 'Suspense', link: '/tutorial/solid/suspense' },
{ text: 'SSR and Testing', link: '/tutorial/solid/scope' },
],
},
{
text: 'React',
collapsed: true,
items: [
{ text: 'Get started', link: '/tutorial/react/' },
{ text: 'Suspense', link: '/tutorial/react/suspense' },
{ text: 'SSR and Testing', link: '/tutorial/react/scope' },
],
},
],
},
{
text: 'React',
text: 'Migration',
collapsed: true,
items: [
{ text: 'Get started', link: '/tutorial/react/' },
{ text: 'Suspense', link: '/tutorial/react/suspense' },
{ text: 'SSR and Testing', link: '/tutorial/react/scope' },
{
text: 'from Effects',
link: '/tutorial/migrate/effector/',
collapsed: true,
items: [
{
text: '1. Wrap existing Effects',
link: '/tutorial/migrate/effector/wrap',
},
{
text: '2. Use add-ons',
link: '/tutorial/migrate/effector/addons',
},
{
text: '3. Add Contracts',
link: '/tutorial/migrate/effector/contracts',
},
{
text: '4. Use specific factories',
link: '/tutorial/migrate/effector/specific_factories',
},
{
text: '5. Use Trigger API',
link: '/tutorial/migrate/effector/trigger_api',
},
{
text: '6. Next steps',
link: '/tutorial/migrate/effector/next',
},
],
},
],
},
],
Expand Down
2 changes: 2 additions & 0 deletions apps/website/docs/tutorial/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,7 @@ Pretty cool, right? We love it, and we hope you will too. Read on to learn more

- Learn Farfetched at your own pace with our amazingly [Thorough Tutorial](/tutorial/install)
- Read framework-specific recommendations for [Solid](/tutorial/solid/) and [React](/tutorial/react/)
- Learn about step-by-step adoption of Farfetched for existing applications which uses different tools for data fetching:
- [Effector's _Effects_](/tutorial/migrate/effector/)
- See the whole picture in [API reference](/api/)
- Check out Farfetched's [roadmap](/roadmap) to stay in the same wavelength with us
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions apps/website/docs/tutorial/migrate/effector/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Migration to Farfetched from plain _Effects_

This tutorial describes how to add Farfetched to an existing application uses [_Effects_](https://effector.dev/docs/api/effector/effect) for data fetching step by step without rewriting big parts of the codebase.

::: tip
This tutorial is not a replacement for the [Thorough Tutorial](/tutorial/install) which is a better starting point for learning Farfetched. Furthermore, it is assumed that you have read [Thorough Tutorial](/tutorial/install) and know the basics of Farfetched.
:::

Farfetched is built with continues adoption in mind, so there are straightforward steps to add it to an existing application and embrace its benefits:

1. [Wrap existing data fetching _Effects_](/tutorial/migrate/effector/wrap) to _Queries_ and _Mutations_
2. [Replace existing add-ons with Farfetched](/tutorial/migrate/effector/addons) operators like `retry`, `cache` or `connectQuery`
3. [Add strict _Contracts_](/tutorial/migrate/effector/contracts) to server responses
4. [Migrate to specific factories](/tutorial/migrate/effector/specific_factories) like `createJsonQuery` and `createJsonMutation`
5. [Apply declarative approach](/tutorial/migrate/effector/trigger_api) with Trigger API and `keepFresh` operator
6. [Continue migrating application step-by-step](/tutorial/migrate/effector/next)
Empty file.
Empty file.
Empty file.
74 changes: 74 additions & 0 deletions apps/website/docs/tutorial/migrate/effector/wrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Step 1: Wrap existing data fetching _Effects_

::: tip
In this tutorial, we assume you have an application that uses [_Effects_](https://effector.dev/docs/api/effector/effect) for data fetching.
:::

Farfetched has two primitives for data fetching: [_Queries_](/api/primitives/query) and [_Mutations_](/api/primitives/mutation). It is a complete replacement for [_Effects_](https://effector.dev/docs/api/effector/effect) used for data fetching. Let's start with a key difference between _Effects_ and _Queries_/_Mutations_.

## _Effects_ vs _Queries_/_Mutations_

## Differences between _Queries_ and _Mutations_

## Wrap _Effects_ to _Queries_ and _Mutations_

All Farfetched APIs are designed to be used with [_Queries_](/api/primitives/query) and [_Mutations_](/api/primitives/mutation). So, to take advantage of Farfetched, we need to wrap existing [_Effects_](https://effector.dev/docs/api/effector/effect) to [_Queries_](/api/primitives/query) and [_Mutations_](/api/primitives/mutation).

```ts
import { createQuery, createMutation } from '@farfetched/core';

const fetchUserFx = createEffect(/*...*/);
const userQuery = createQuery({ effect }); // [!code ++]

const createPostFx = createEffect(/*...*/);
const createPostMutation = createMutation({ effect }); // [!code ++]
```

After this change, instead of direct usage of [_Effects_](https://effector.dev/docs/api/effector/effect) we have to use [_Queries_](/api/primitives/query) and [_Mutations_](/api/primitives/mutation).

```ts
// Use .start Event instead of Effect
sample({
clock: someTrigger,
target: fetchUserFx, // [!code --]
target: userQuery.start, // [!code ++]
});

// Use .finished.success Event instead of .done Event
sample({
clock: fetchUserFx.done, // [!code --]
clock: userQuery.finished.success, // [!code ++]
target: someTarget,
});

// Use .finished.failure Event instead of .fail Event
sample({
clock: fetchUserFx.fail, // [!code --]
clock: userQuery.finished.failure, // [!code ++]
target: someTarget,
});

// Use .$data Store instead of creating a new Store
const $user = createStore(null); // [!code --]
$user.on(fetchUserFx.doneData, (_, newUser) => newUser); // [!code --]
const $user = userQuery.$data; // [!code ++]
```

As soon as no code in the application uses [_Effects_](https://effector.dev/docs/api/effector/effect) directly, we can hide them to prevent accidental usage.

```ts
const fetchUserFx = createEffect(/*...*/); // [!code --]
const userQuery = createQuery({ effect }); // [!code --]

const userQuery = createQuery({ effect: createEffect(/*...*/) }); // [!code ++]
```

This simple step allows us to use Farfetched APIs with existing [_Effects_](https://effector.dev/docs/api/effector/effect) without rewriting big parts of the codebase. For example, now we can easily add retries to `userQuery`:

```ts
import { retry } from '@farfetched/core';

retry(userQuery, { limit: 3, delay: 1000 });
```

We will dive into more details about Farfetched APIs in the next steps of this tutorial.