Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Commit

Permalink
feat(blueprints): add a basic HTTP client factory blueprint
Browse files Browse the repository at this point in the history
closes #27
  • Loading branch information
paul-thebaud committed Aug 7, 2023
1 parent ce760e1 commit 06ef473
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 23 deletions.
2 changes: 2 additions & 0 deletions src/blueprints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import restExtension from '@/blueprints/extensions/restExtension';
import jsonApiStarterExtensions from '@/blueprints/extensions/starters/jsonApiStarterExtensions';
import restStarterExtensions from '@/blueprints/extensions/starters/restStarterExtensions';
import writeExtensions from '@/blueprints/extensions/writeExtension';
import makeHttpClient from '@/blueprints/http/makeHttpClient';
import appendJsonApiParams from '@/blueprints/jsonapi/appendJsonApiParams';
import makeJsonApi from '@/blueprints/jsonapi/makeJsonApi';
import makeCache from '@/blueprints/makeCache';
Expand All @@ -20,6 +21,7 @@ export {
makeJsonApi,
appendJsonApiParams,
makeJsonRest,
makeHttpClient,
coreExtensions,
readExtensions,
writeExtensions,
Expand Down
30 changes: 30 additions & 0 deletions src/blueprints/http/makeHttpClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { context, makeActionClass } from '@/core';
import { HttpAdapter } from '@/http';
import { makeActionFactoryMockable } from '@/test';

/**
* Create the dependencies and action factory to interact with any
* HTTP backend using a simple client.
*
* @param config
*/
export default function makeHttpClient<
Extension extends {} = {},
>(config: {
baseURL?: string;
extensions?: Extension;
} = {}) {
const adapter = new HttpAdapter({
baseURL: config.baseURL ?? '/api/v1',
});

const Action = makeActionClass(config.extensions);
const withDependencies = context({ adapter });

return {
adapter,
withDependencies,
Action,
action: makeActionFactoryMockable(() => new Action().use(withDependencies)),
};
}
7 changes: 7 additions & 0 deletions website/docs/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ import Tabs from '@theme/Tabs';

:::

:::info

Only here for a simple HTTP client? Check out
[**the simple HTTP client guide**](/docs/guides/actions/http-client).

:::

## Your first model

Models represent the structure of your data and are used to simplify and
Expand Down
3 changes: 2 additions & 1 deletion website/docs/guides/actions/action-factory-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ match your data source needs.

You can customize the dependencies when
[using a blueprint action factory](/docs/getting-started#with-blueprints) or
when using a [custom action factory](/docs/guides/actions/custom-action-factory).
when using a
[custom action factory](/docs/guides/actions/custom-action-factory).

In this guide, we will see how to customize dependencies configuration through
the REST blueprint action factory as an example. For this, each configurable
Expand Down
64 changes: 64 additions & 0 deletions website/docs/guides/actions/http-client.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
sidebar_position: 10
description: Using Foscia as a simple HTTP client.
---

import Link from '@docusaurus/Link';

# HTTP client

:::tip What you'll learn

- Configuring your action factory to only make HTTP request
- Using Foscia as an HTTP client

:::

## Creating the action factory

**If you are using a REST or JSON:API blueprints, you can already use your
action as an HTTP client.**

You can use Foscia as a simple HTTP client (just like Axios).
For this, you can configure an HTTP client action factory.


```javascript title="action.js"
import { makeHttpClient } from 'foscia/blueprints';

const { action } = makeHttpClient({
baseURL: 'https://example.com',
});

export default action;
```

## Using the HTTP client features

Once your action factory is ready, sending HTTP request is pretty easy:

```javascript
import { makeGet, makePost } from 'foscia/http';
import { action } from './action';

// GET https://example.com/
const response = await action()
.use(makeGet('/'))
.run(raw());

// GET https://example.com/api/posts (and get JSON payload)
const data = await action()
.use(makePost('/api/posts', {
data: { title: 'Hello World!' },
}))
.run(raw((response) => response.json()));
```

<Link className="button bg--primary" to="/docs/reference/actions-enhancers#http">
Read the HTTP' enhancers API guide
</Link>

## Implementation notes

You may learn more about the HTTP adapter capabilities and implementation
on [the HTTP implementation guide](/docs/guides/implementations/http).
39 changes: 19 additions & 20 deletions website/docs/guides/models/models-changes-tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ description: Tracking models states change (values, etc.).

:::tip What you'll learn

- Tracking a model's instance changes
- Creating snapshots of a model's instance
- Restoring snapshots of a model's instance
- Tracking a model's instance changes
- Creating snapshots of a model's instance
- Restoring snapshots of a model's instance

:::

Foscia will track changes over your instances properties (IDs, attributes
or relations) throughout their existence.
Foscia will track changes over your instances properties (IDs, attributes or
relations) throughout their existence.

Each time you send/fetch an instance to/from your data source, your instance's
properties will be synced in an "original" snapshot.

This original snapshot allows you to check if some properties have changed
since last synchronization.
This original snapshot allows you to check if some properties have changed since
last synchronization.

## Taking a snapshot

You can take a snapshot of an instance at any time using `takeSnapshot`.
This is done automatically every time you send/fetch an instance to/form
your data source, and the created snapshot is saved into the `$original`
properties of your instance.
You can take a snapshot of an instance at any time using `takeSnapshot`. This is
done automatically every time you send/fetch an instance to/form your data
source, and the created snapshot is saved into the `$original` properties of
your instance.

```javascript
import { takeSnapshot } from 'foscia/core';
Expand All @@ -37,10 +37,9 @@ const myPostSnapshot = takeSnapshot(myPost);

## Checking for changes

To check for changes between two snapshots, you can use `compareSnapshots`.
To check for changes between an instance and its original snapshot, you
can use `changed` (this will automatically take a new snapshot
and compare against it).
To check for changes between two snapshots, you can use `compareSnapshots`. To
check for changes between an instance and its original snapshot, you can use
`changed` (this will automatically take a new snapshot and compare against it).

```javascript
import { changed, compareSnapshots, takeSnapshot } from 'foscia/core';
Expand All @@ -58,8 +57,8 @@ compareSnapshots(takeSnapshot(myPost), myPost.$original, ['title']);

## Syncing changes

You can mark your instance as synced any time using `markSynced`.
Just like other helper functions, you can affect only specific properties.
You can mark your instance as synced any time using `markSynced`. Just like
other helper functions, you can affect only specific properties.

```javascript
import { markSynced } from 'foscia/core';
Expand All @@ -72,9 +71,9 @@ markSynced(myPost, ['title']);

## Restoring changes

You can restore a snapshot on your model as synced any time using `restore`
and `restoreSnapshot`.
Just like other helper functions, you can affect only specific properties.
You can restore a snapshot on your model as synced any time using `restore` and
`restoreSnapshot`. Just like other helper functions, you can affect only
specific properties.

```javascript
import { restore, restoreSnapshot } from 'foscia/core';
Expand Down
4 changes: 2 additions & 2 deletions website/docs/guides/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ the action factory function is already a mockable function (a mock can be
installed on it) and you have nothing else to do.

If you are building your
[own action factory function](docs/guides/actions/custom-action-factory), you can make
any factory function mockable using `makeActionFactoryMockable`:
[own action factory function](docs/guides/actions/custom-action-factory), you
can make any factory function mockable using `makeActionFactoryMockable`:

```typescript title="action.ts"
function action() {
Expand Down

0 comments on commit 06ef473

Please sign in to comment.