Skip to content

Commit 729de51

Browse files
committed
docs: Fill in 0.9 release post
1 parent 45cdb1b commit 729de51

File tree

3 files changed

+513
-5
lines changed

3 files changed

+513
-5
lines changed

docs/rest/api/Query.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ the same high performance and referential equality guarantees expected of Reacti
2424

2525
[Schema](./schema.md) used to retrieve/denormalize data from the Reactive Data Client cache.
2626
This accepts any [Queryable](/rest/api/schema#queryable) schema: [Entity](./Entity.md), [All](./All.md), [Collection](./Collection.md), [Query](./Query.md),
27-
and [Union](./Union.md).
27+
[Union](./Union.md), and [Object](./Object.md) schemas for joining multiple entities.
2828

2929
### process(entries, ...args) {#process}
3030

@@ -205,6 +205,77 @@ render(<TodosPage />);
205205

206206
</HooksPlayground>
207207

208+
### Object Schema Joins {#object-schema-joins}
209+
210+
`Query` can take [Object Schemas](/rest/api/Object), enabling joins across multiple entity types. This allows you to combine data from different entities in a single query.
211+
212+
<HooksPlayground groupId="schema" defaultOpen="y" fixtures={[
213+
{
214+
endpoint: new RestEndpoint({path: '/tickers/:product_id'}),
215+
args: [{ product_id: 'BTC-USD' }],
216+
response: { product_id: 'BTC-USD', price: 45000 },
217+
delay: 150,
218+
},
219+
{
220+
endpoint: new RestEndpoint({path: '/stats/:product_id'}),
221+
args: [{ product_id: 'BTC-USD' }],
222+
response: { product_id: 'BTC-USD', last: 44950 },
223+
delay: 150,
224+
},
225+
]}>
226+
227+
```ts title="resources/Ticker" collapsed
228+
export class Ticker extends Entity {
229+
product_id = '';
230+
price = 0;
231+
pk() { return this.product_id; }
232+
}
233+
234+
export const TickerResource = resource({
235+
path: '/tickers/:product_id',
236+
schema: Ticker,
237+
});
238+
```
239+
240+
```ts title="resources/Stats" collapsed
241+
export class Stats extends Entity {
242+
product_id = '';
243+
last = 0;
244+
pk() { return this.product_id; }
245+
}
246+
247+
export const StatsResource = resource({
248+
path: '/stats/:product_id',
249+
schema: Stats,
250+
});
251+
```
252+
253+
```tsx title="PriceDisplay"
254+
import { schema } from '@data-client/rest';
255+
import { useQuery, useFetch } from '@data-client/react';
256+
import { TickerResource, Ticker } from './resources/Ticker';
257+
import { StatsResource, Stats } from './resources/Stats';
258+
259+
// Join Ticker and Stats by product_id
260+
const queryPrice = new schema.Query(
261+
{ ticker: Ticker, stats: Stats },
262+
({ ticker, stats }) => ticker?.price ?? stats?.last,
263+
);
264+
265+
function PriceDisplay({ productId }: { productId: string }) {
266+
useFetch(TickerResource.get, { product_id: productId });
267+
useFetch(StatsResource.get, { product_id: productId });
268+
const price = useQuery(queryPrice, { product_id: productId });
269+
270+
if (price === undefined) return <div>Loading...</div>;
271+
return <div>Price: ${price}</div>;
272+
}
273+
274+
render(<PriceDisplay productId="BTC-USD" />);
275+
```
276+
277+
</HooksPlayground>
278+
208279
### Fallback joins
209280

210281
import StackBlitz from '@site/src/components/StackBlitz';

0 commit comments

Comments
 (0)