Skip to content

Commit aaa8f31

Browse files
committed
Initial sheets guide
1 parent 3bb2ac5 commit aaa8f31

File tree

4 files changed

+374
-20
lines changed

4 files changed

+374
-20
lines changed

.vscode/settings.json

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"[markdown]": {
3+
"editor.rulers": [80]
4+
},
5+
"[mdx]": {
6+
"editor.rulers": [80]
7+
},
8+
}

src/content/docs/docs/guides/sheets.md

-19
This file was deleted.
+362
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,362 @@
1+
---
2+
title: Reading Sheets
3+
sidebar:
4+
order: 3
5+
---
6+
7+
import { LinkCard } from '@astrojs/starlight/components';
8+
9+
<LinkCard
10+
title="API Reference"
11+
href="/api/1/docs#tag/sheets"
12+
description="OpenAPI specification for sheet endpoints."
13+
/>
14+
15+
Sheet endpoints retrieve data for one or more rows from a sheet, mapping values
16+
to match a schema. Pinning is available for both game version and schema for
17+
these endpoints, see [Ensuring Stability] for more information.
18+
19+
[Ensuring Stability]: /docs/guides/pinning/
20+
21+
## Language
22+
23+
Sheets with user-facing strings are commonly localised into all the languages
24+
supported by the game client. For more details on localisations and game
25+
editions, refer to [Important Concepts][concepts-localisations].
26+
27+
While XIVAPI defaults to English text in responses, other languages may be
28+
requested with the `language` parameter.
29+
30+
```json /language=(ja|en|de|fr)/
31+
// /api/1/sheet/Item/42589?fields=Name&language=ja
32+
{ "fields": { "Name": "天使の筆" } }
33+
// /api/1/sheet/Item/42589?fields=Name&language=en
34+
{ "fields": { "Name": "Angel Brush" } }
35+
// /api/1/sheet/Item/42589?fields=Name&language=de
36+
{ "fields": { "Name": "Engelspinsel" } }
37+
// /api/1/sheet/Item/42589?fields=Name&language=fr
38+
{ "fields": { "Name": "Pinceau angélique" } }
39+
```
40+
41+
[concepts-localisations]: /docs/guides/concepts/#editions--localisations
42+
43+
## Fields
44+
45+
Fields comprise the majority of the response for sheet endpoints. A number of
46+
tools are available to filter and tune the way fields are represented in
47+
responses.
48+
49+
### Types
50+
51+
All fields have a type derived from a combination of the game data and schema in
52+
use. Types are used to define the overall structure of the data and how it is
53+
read.
54+
55+
Scalar
56+
: The most common field type, scalars represent a single value such as a number,
57+
string, or boolean.
58+
59+
Struct
60+
: Sometimes, sheets contain a collection of related fields. Schemas may
61+
represent this as a struct, grouping the fields under a shared parent field in
62+
the response.
63+
64+
Array
65+
: When consecutive fields represent a repetition of a value, schemas may group
66+
them into an array. Arrays always have a fixed length - unused entries are
67+
typically set to a null or zero state.
68+
69+
Additionally, scalars may have additional semantics supplied by their type:
70+
71+
Relationship
72+
: Field with values that represent a link to another sheet. Refer to
73+
[field relationships] for further information.
74+
75+
Icon
76+
: Numeric values representing an icon asset ID. XIVAPI will pre-compute the
77+
relevant paths for accessing the asset.
78+
79+
[field relationships]: /docs/guides/concepts#relationships
80+
81+
### Filtering
82+
83+
Sheets regularly contain more information than is needed for a single use-case.
84+
This quickly compounds when field relationships are present to link in
85+
additional rows of data. For example, the [full response][pct brush full] for
86+
the "Angel Brush" `Item` is over 80kB before compression, representing
87+
approximately 6500 lines of formatted JSON.
88+
89+
[pct brush full]: /api/1/sheet/Item/42589
90+
91+
To reduce the amount of unnecessary data in responses, the `fields` parameter
92+
can be used to specify a subset of fields that should be included:
93+
94+
<details>
95+
<summary><code>fields=Name,LevelEquip</code></summary>
96+
97+
```json "Name" "LevelEquip"
98+
// /api/1/sheet/Item/42589?fields=Name,LevelEquip
99+
{
100+
"fields": {
101+
"Name": "Angel Brush",
102+
"LevelEquip": 99
103+
}
104+
}
105+
```
106+
107+
</details>
108+
109+
If a field is nested within a struct or relationship, dot notation is used to
110+
specify the path to access it:
111+
112+
<details>
113+
<summary><code>fields=ItemUICategory.Name</code></summary>
114+
115+
```json "ItemUICategory.Name" "ItemUICategory" "Name"
116+
// /api/1/sheet/Item/42589?fields=ItemUICategory.Name
117+
{
118+
"fields": {
119+
"ItemUICategory": {
120+
"fields": {
121+
"Name": "Pictomancer's Arm"
122+
}
123+
}
124+
}
125+
}
126+
```
127+
128+
</details>
129+
130+
Array fields may be specified to retrieve values from all entries:
131+
132+
<details>
133+
<summary><code>fields=BaseParam[].Name</code></summary>
134+
135+
```json "BaseParam[]" "BaseParam"
136+
// /api/1/sheet/Item/42589?fields=BaseParam[].Name
137+
{
138+
"fields": {
139+
"BaseParam": [
140+
{ "fields": { "Name": "Intelligence" } },
141+
{ "fields": { "Name": "Vitality" } }
142+
// ...
143+
]
144+
}
145+
}
146+
```
147+
148+
</details>
149+
150+
:::tip[Not sure what field you want?]
151+
152+
You can omit the `fields` parameter on the `/sheet/{sheet}/{row}` endpoint to
153+
see every field available for the given game version and schema. Fair warning,
154+
there may be quite a few!
155+
156+
:::
157+
158+
### Decorators
159+
160+
In addition to filtering the fields in the response, the `fields` parameter can
161+
also be used to specify "decorators" that modify how the field is read or
162+
presented in responses. To avoid collisions, decorators are included in the
163+
response field name.
164+
165+
#### `@lang(<lang>)`
166+
167+
While the `language` parameter can be used to change the default language used
168+
in a request, it may be necessary to retrieve two or more languages in the same
169+
request.
170+
171+
<details>
172+
<summary><code>fields=Name,Name@lang(ja)</code></summary>
173+
174+
```json "Name@lang(ja)"
175+
// /api/1/sheet/Item/42589?fields=Name,Name@lang(ja)
176+
{
177+
"fields": {
178+
"Name": "Angel Brush",
179+
"Name@lang(ja)": "天使の筆"
180+
}
181+
}
182+
```
183+
184+
</details>
185+
186+
If specified on a structural field, the provided language will act as the
187+
default for any nested fields:
188+
189+
<details>
190+
<summary><code>fields=ItemUICategory@lang(de).Name</code></summary>
191+
192+
```json "ItemUICategory@lang(de)"
193+
// /api/1/sheet/Item/42589?fields=ItemUICategory@lang(de).Name
194+
{
195+
"fields": {
196+
"ItemUICategory@lang(de)": {
197+
"fields": {
198+
"Name": "Hauptwaffe der Piktomanten"
199+
}
200+
}
201+
}
202+
}
203+
```
204+
205+
</details>
206+
207+
#### `@as(<transform>)`
208+
209+
The `as` decorator performs transformations on fields to tailor the resulting
210+
values for particular use cases.
211+
212+
`@as(raw)` will prevent processing of field types such as relationships and
213+
icons, useful if the rich data is not going to be utilised.
214+
215+
<details>
216+
<summary><code>fields=ItemUICategory,ItemUICategory@as(raw)</code></summary>
217+
218+
```json "ItemUICategory@as(raw)"
219+
// /api/1/sheet/Item/42589?fields=ItemUICategory,ItemUICategory@as(raw)
220+
{
221+
"fields": {
222+
"ItemUICategory": {
223+
"value": 111,
224+
// ...
225+
"fields": {
226+
// ...
227+
}
228+
},
229+
"ItemUICategory@as(raw)": 111
230+
}
231+
}
232+
```
233+
234+
</details>
235+
236+
`@as(html)` formats string values into HTML fragments, with support for most
237+
text and formatting features in the game's rich text format.
238+
239+
<details>
240+
<summary><code>fields=Description,Description@as(html)</code></summary>
241+
242+
```json wrap "Description@as(html)"
243+
// /api/1/sheet/Item/44104?fields=Description,Description@as(html)
244+
{
245+
"fields": {
246+
"Description": "Warm flour tortillas filled with slices of marinated rroneek chuck that has been grilled to a smoky char.\n\nEXP Bonus: +3% Duration: 30m\n(Duration can be extended to 60m by consuming multiple servings)",
247+
"Description@as(html)": "Warm flour tortillas filled with slices of marinated rroneek chuck that has been grilled to a smoky char.<br><br><span style=\"color:rgba(0,204,34,1);\">EXP Bonus:</span> +3% <span style=\"color:rgba(0,204,34,1);\">Duration:</span> 30m<br>(Duration can be extended to 60m by consuming multiple servings)"
248+
}
249+
}
250+
```
251+
252+
</details>
253+
254+
### Transient Sheets
255+
256+
As [outlined prior][transient sheets], related data may be split into two or
257+
more sheets as an implementation detail. To reduce the number of requests needed
258+
to retrieve data, the API attempts to find transient sheets, and includes their
259+
content in a top-level `transient` key, when available.
260+
261+
To control these fields, the `transient` parameter can be provided. It accepts
262+
identical syntax to the `fields` parameter [outlined above](#fields).
263+
264+
<details>
265+
<summary><code>transient=Description@as(html)</code></summary>
266+
267+
```json wrap "transient"
268+
// /api/1/sheet/Action/34684?transient=Description@as(html)
269+
{
270+
"fields": {
271+
// ...
272+
},
273+
"transient": {
274+
"Description@as(html)": "Quickly dash 15 yalms forward.<br><span style=\"color:rgba(0,204,34,1);\">Additional Effect: </span>Increases movement speed<br><span style=\"color:rgba(0,204,34,1);\">Duration: </span>5s<br>Cannot be executed while bound."
275+
}
276+
}
277+
```
278+
279+
</details>
280+
281+
:::note
282+
283+
The check for transient sheets is naive - a request for the sheet `Example` will
284+
blindly return data for matching rows in the `ExampleTransient` sheet, if it
285+
exists.
286+
287+
While this approach works well for the majority of instances, always verify that
288+
the data looks appropriate before committing to using transient values.
289+
290+
:::
291+
292+
[transient sheets]: /docs/guides/concepts/#transient-sheets
293+
294+
## Multiple Rows
295+
296+
All of the examples above have used the single-row endpoint,
297+
`/api/1/sheet/{sheet}/{row}`. If more than one row from the same sheet is
298+
desired, the row list endpoint is available.
299+
300+
All parameters outlined above are also available for the row list.
301+
302+
By default, it will list all rows in ID order, starting from the first.
303+
304+
```json
305+
// /api/1/sheet/Item?fields=Name
306+
{
307+
"rows": [
308+
{ "row_id": 0, "fields": { "Name": "" } },
309+
{ "row_id": 1, "fields": { "Name": "Gil" } },
310+
{ "row_id": 2, "fields": { "Name": "Fire Shard" } },
311+
// ...
312+
]
313+
}
314+
```
315+
316+
If provided, the `after` parameter will skip any rows less than or equal to the
317+
specified row ID. Additionally, the `limit` parameter can be used to adjust the
318+
maximum number of results returned in one response. Excessively large `limits`
319+
will be clamped to a server-defined maximum.
320+
321+
<details>
322+
<summary><code>after=1&limit=2</code></summary>
323+
324+
```json "after=1" "limit=2"
325+
// /api/1/sheet/Item?fields=Name&after=1&limit=2
326+
{
327+
"rows": [
328+
{ "row_id": 2, "fields": { "Name": "Fire Shard" } },
329+
{ "row_id": 3, "fields": { "Name": "Ice Shard" } }
330+
]
331+
}
332+
```
333+
334+
</details>
335+
336+
Alternatively, a list of row IDs can be provided if already know - useful for
337+
retrieving a batch of rows from a sheet.
338+
339+
<details>
340+
<summary><code>rows=1,29,46</code></summary>
341+
342+
```json /(?:rows=|row_id": )(1)/ "29" "46"
343+
// /api/1/sheet/Item?fields=Name&rows=1,29,46
344+
{
345+
"rows": [
346+
{ "row_id": 1, "fields": { "Name": "Gil" } },
347+
{ "row_id": 29, "fields": { "Name": "MGP" } },
348+
{ "row_id": 46, "fields": { "Name": "Allagan Tomestone of Aesthetics" } }
349+
]
350+
}
351+
```
352+
353+
</details>
354+
355+
:::caution
356+
357+
Row IDs are **not** guaranteed to be contiguous, as many sheets contain
358+
significant "holes" of unused IDs. In most cases, these IDs will not be present
359+
in data, and will be skipped or ignored when requested, including when
360+
iterating.
361+
362+
:::

0 commit comments

Comments
 (0)