Skip to content

Commit

Permalink
docs: /docs/concepts/features-overview/ (#725)
Browse files Browse the repository at this point in the history
- Re-does the feature overview page of the documentation.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added a "Features Roadmap" component to the website, displaying a list
of features with details and links.

- **Documentation**
- Updated various guides and reference documents to improve clarity and
presentation of code examples.
- Added new sections for various features such as Typegate, Typegraph,
Runtimes, Prisma, Auth, Tooling, and SDK.

- **Bug Fixes**
  - Corrected a typo in the GraphQL runtimes reference documentation.

- **Refactor**
- Replaced `SDKTabs` and `TabItem` components with `TGExample` for
better code example presentation.
- Adjusted the `MiniQL` component to handle optional properties and
default settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Yohe-Am <[email protected]>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
Yohe-Am and coderabbitai[bot] authored May 22, 2024
1 parent 24963ce commit b6788a6
Show file tree
Hide file tree
Showing 8 changed files with 938 additions and 187 deletions.
810 changes: 785 additions & 25 deletions website/docs/concepts/features-overview/index.mdx

Large diffs are not rendered by default.

52 changes: 4 additions & 48 deletions website/docs/guides/external-functions/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
sidebar_position: 50
---

import SDKTabs from "@site/src/components/SDKTabs";
import TabItem from "@theme/TabItem";
import TGExample from "@site/src/components/TGExample";
import CodeBlock from "@theme-original/CodeBlock";

Expand All @@ -21,28 +19,13 @@ Custom functions are commonly used for:

The following example uses the `DenoRuntime` to respond to requests and define a policy.

<SDKTabs>
<TabItem value="typescript">

<TGExample
typegraph="math"
python={require("!!code-loader!../../../../examples/typegraphs/math.ts")}
query={require('./math.graphql')}
/>

</TabItem>

<TabItem value="python">

<TGExample
typegraph="math"
typescript={require("!!code-loader!../../../../examples/typegraphs/math.ts")}
python={require("../../../../examples/typegraphs/math.py")}
query={require('./math.graphql')}
/>

</TabItem>
</SDKTabs>

Note that for the `fib` root materializer, we're using a typescript module in an external file.
Here's what `scripts/fib.ts` looks like:

Expand All @@ -63,29 +46,15 @@ The following feature is currently only implemented for the `DenoRuntime`.
:::

On some runtimes, custom functions are passed the context object along with the materializer inputs.
This object provides access to all kind of information about the context in which the function is running.
This object provides access to all kinds of information about the context in which the function is running.
The following example illustrates availaible fields:

<SDKTabs>
<TabItem value="typescript">

<TGExample
typegraph="func-ctx"
typescript={require("!!code-loader!../../../../examples/typegraphs/func-ctx.ts")}
python={require("!!code-loader!../../../../examples/typegraphs/func-ctx.py")}
query={require('./ctx.graphql')}
/>
</TabItem>

<TabItem value="python">

<TGExample
typegraph="func-ctx"
typescript={require("!!code-loader!../../../../examples/typegraphs/func-ctx.py")}
query={require('./ctx.graphql')}
/>

</TabItem>
</SDKTabs>

Note, the typescript version of the sample uses a closure instead of a string snippet to define the function.
This is a simple syntax sugar availaible when using `DenoRuntime` through the typescript sdk or the `PythonRuntime` the python one.
Expand All @@ -102,26 +71,13 @@ The primary way of doing this is by sending GraphqQl queries from within your fu
On the `DenoRuntime`, to make this easier, there's a `gql` object passed to all functions.
The following exapmle illustrates how it functions:

<SDKTabs>
<TabItem value="typescript">

<TGExample
typegraph="func-gql"
typescript={require("!!code-loader!../../../../examples/typegraphs/func-gql.ts")}
query={require('./gql.graphql')}
/>
</TabItem>

<TabItem value="python">

<TGExample
typegraph="func-gql"
typescript={require("!!code-loader!../../../../examples/typegraphs/func-gql.py")}
python={require("!!code-loader!../../../../examples/typegraphs/func-gql.py")}
query={require('./gql.graphql')}
/>

</TabItem>
</SDKTabs>

And `scripts/createVote.ts` looks like:

Expand Down
25 changes: 8 additions & 17 deletions website/docs/guides/rest/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,24 @@
sidebar_position: 50
---

import SDKTabs from "@site/src/components/SDKTabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme-original/CodeBlock";
import TGExample from "@site/src/components/TGExample";

# Write REST endpoints

The root materializers, the ones we expose from our typegraphs, are served through a GraphQl API over HTTP.
In addition, we can also expose [REST](https://en.wikipedia.org/wiki/REST) APIs using the `rest` method.
The method takes GraphQl queries and provides RESTly endpoints for them.

<SDKTabs>
<TabItem value="typescript">
<TGExample
python={require("!!code-loader!../../../../examples/typegraphs/example_rest.py")}
typescript={require("!!code-loader!../../../../examples/typegraphs/example_rest.ts")}
disablePlayground
/>

<CodeBlock language="typescript">{require("!!code-loader!../../../../examples/typegraphs/example_rest.ts").content}</CodeBlock>

</TabItem>

<TabItem value="python">

<CodeBlock language="python">{require("../../../../examples/typegraphs/example_rest.py").content}</CodeBlock>

</TabItem>
</SDKTabs>

The effect of the root materializer accessed in the query determines the HTTP verb used and the mapping can be found [here](/docs/reference/types/functions#effects).
The effect of the root materializer accessed in the query determines the HTTP verb used, and the mapping can be found [here](/docs/reference/types/functions#effects).

There's also an OpenAPI schema generated from the rest endpoints served under `{typegate_url}/{typegraph}/rest/_schema`.
A browser based explorer for the OpenAPI schema is served under `{typegate_url}/{typegraph}/rest` as well.
A browser-based explorer for the OpenAPI schema is served under `{typegate_url}/{typegraph}/rest` as well.

{/* todo: link to the expample's redoc*/}
49 changes: 5 additions & 44 deletions website/docs/guides/securing-requests/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
sidebar_position: 50
---

import TGExample from "@site/src/components/TGExample";
import Cors from "@site/shared/cors/index.mdx";
import SDKTabs from "@site/src/components/SDKTabs";
import TabItem from "@theme/TabItem";
import TGExample from "@site/src/components/TGExample";

# Secure your requests

Expand All @@ -28,36 +27,17 @@ Basic authentication relies on a username and password pair.
We specify the password through typegraph secrets with the format `BASIC_{username}`.
In this case, the secret `BASIC_andim=password` is set.

<SDKTabs>
<TabItem value="typescript">

<TGExample
typegraph="authentication"
typescript={require("!!code-loader!../../../../examples/typegraphs/authentication.ts")}
query={require("./authentication.graphql")}
headers={{
Authorization: "Basic YW5kaW06cGFzc3dvcmQ=",
}}
tab="headers"
/>

</TabItem>

<TabItem value="python">

<TGExample
typegraph="authentication"
python={require("../../../../examples/typegraphs/authentication.py")}
typescript={require("!!code-loader!../../../../examples/typegraphs/authentication.ts")}
query={require("./authentication.graphql")}
headers={{
Authorization: "Basic YW5kaW06cGFzc3dvcmQ=",
}}
tab="headers"
/>

</TabItem>
</SDKTabs>

Note, the token is encoded in base64.
Decoded, it'd read `andim:password`.

Expand Down Expand Up @@ -95,25 +75,9 @@ typegates:
BASIC_user: "user_pass"
```
<SDKTabs>
<TabItem value="typescript">
<TGExample
typegraph="policies"
python={require("!!code-loader!../../../../examples/typegraphs/policies.ts")}
query={require('./policies.graphql')}
headers={{
Authorization: "Basic YWRtaW46YWRtaW5fcGFzcw==",
}}
tab="headers"
/>
</TabItem>
<TabItem value="python">
<TGExample
typegraph="policies"
typescript={require("!!code-loader!../../../../examples/typegraphs/policies.ts")}
python={require("../../../../examples/typegraphs/policies.py")}
query={require('./policies.graphql')}
headers={{
Expand All @@ -122,11 +86,8 @@ typegates:
tab="headers"
/>
</TabItem>
</SDKTabs>
More than one policies can be attached to a single materalizer and combining policies allow for compositionaly defining our access control rules.
If a materalizer has more one policies, they are evaluated in turn and:
More than one policy can be attached to a single materalizer and combining policies allows for compositionaly defining our access control rules.
If a materalizer has more than one policy, they are evaluated in turn and:
- If any one of attached policy returns `true`, the request immediately gains access.
- If a policy returns `false`, the request is immediately denied access.
Expand Down
6 changes: 3 additions & 3 deletions website/docs/reference/runtimes/graphql/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ Update `typegraph.py` with the highlighted lines below:
query={require("./graphql.graphql")}
/>

Again, a few interesting happened here:
Again, a few interesting things happened here:

1. No migration has been run. The field `user` comes from another runtime and doesn't exist in the database. The typegate will orchestrate the query execution in all runtimes and minimize the work done.
2. The `from_parent` rule automatically fills the input type with the parent field named `uid`. The `g(·)` rule allows making named reference to another type and avoid circular reference.
2. The `from_parent` rule automatically fills the input type with the parent field named `uid`. The `g(·)` rule allows making named references to another type and avoids circular references.

Other type enforcement rules also exists:
Other type enforcement rules also exist:

- `from_secret(key)` to fill the input type with the secret in the `TG_[typegraph name]_[key]` format
- `from_context(·)` to fill the input type with content from the request context, such as JSON Web Token (JWT), etc.
Expand Down
17 changes: 0 additions & 17 deletions website/shared/s3/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import TGExample from "@site/src/components/TGExample";
import SDKTabs from "@site/src/components/SDKTabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme-original/CodeBlock";

The [S3Runtime](/docs/reference/runtimes/s3) can be used to interact with object storage APIs that are S3 compatible.
Expand Down Expand Up @@ -44,26 +42,11 @@ typegates:

Our typegraph will then look something like:

<SDKTabs>
<TabItem value="typescript">

<TGExample
typegraph="files-upload"
typescript={require("!!code-loader!../../../examples/typegraphs/files-upload.ts")}
query={require('./files.graphql')}
/>

</TabItem>

<TabItem value="python">

<TGExample
typegraph="files-upload"
python={require("../../../examples/typegraphs/files-upload.py")}
query={require('./files.graphql')}
/>

</TabItem>
</SDKTabs>

Peruse the [reference](/docs/reference/runtimes/s3) on the `S3Runtime` for more information.
69 changes: 36 additions & 33 deletions website/src/components/MiniQL/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ import { useSDK } from "../../states/sdk";
import TabItem from "@theme/TabItem";

export interface MiniQLProps {
typegraph: string;
query: ast.DocumentNode;
code?: Array<{
content: string;
codeLanguage?: string;
codeFileUrl?: string;
}>;
typegraph?: string;
query?: ast.DocumentNode;
headers?: Record<string, unknown>;
variables?: Record<string, unknown>;
panel?: Panel;
noTool?: boolean;
defaultMode?: keyof typeof modes | null;
disablePlayground: boolean
disablePlayground?: boolean;
}

function Loader() {
Expand Down Expand Up @@ -71,7 +71,7 @@ function MiniQLBrowser({
createGraphiQLFetcher({
url: `${tgUrl}/${typegraph}`,
}),
[]
[],
);

const [mode, setMode] = useState(defaultMode);
Expand All @@ -80,23 +80,15 @@ function MiniQLBrowser({
// console.log(code);
return (
<div className="@container miniql mb-4">
{defaultMode ? (
<ChoicePicker choices={modes} choice={mode} onChange={setMode} />
) : null}
<GraphiQLProvider
fetcher={fetcher}
defaultQuery={query.loc?.source.body.trim()}
defaultHeaders={JSON.stringify(headers)}
shouldPersistHeaders={true}
variables={JSON.stringify(variables)}
storage={storage}
>
<div
className={`${
defaultMode ? "" : "md:grid @2xl:grid-cols-2"
{(defaultMode && !disablePlayground)
? <ChoicePicker choices={modes} choice={mode!} onChange={setMode} />
: null}
<div
className={`${(defaultMode || disablePlayground) ? "" : "md:grid @2xl:grid-cols-2"
} gap-2 w-full order-first`}
>
{!defaultMode || mode === "typegraph" ? (
>
{disablePlayground || !defaultMode || mode === "typegraph"
? (
<div className=" bg-slate-100 rounded-lg flex flex-col mb-2 md:mb-0 relative">
<ChoicePicker
choices={{
Expand Down Expand Up @@ -126,21 +118,32 @@ function MiniQLBrowser({
))}
</ChoicePicker>
</div>
) : null}
{!disablePlayground && (!defaultMode || mode === "playground") ? (
<div className="flex flex-col graphiql-container">
<div className="flex-1 graphiql-session">
<GraphiQLInterface defaultTab={panel} noTool={noTool} />
</div>
)
: null}
{!disablePlayground && (!defaultMode || mode === "playground")
? (
<GraphiQLProvider
fetcher={fetcher}
defaultQuery={query!.loc?.source.body.trim()}
defaultHeaders={JSON.stringify(headers)}
shouldPersistHeaders={true}
variables={JSON.stringify(variables)}
storage={storage}
>
<div className="flex flex-col graphiql-container">
<div className="flex-1 graphiql-session">
<GraphiQLInterface defaultTab={panel} noTool={noTool} />
</div>

<div className="flex-auto graphiql-response min-h-[200px] p-2 mt-2 bg-slate-100 rounded-lg">
<Loader />
<ResponseEditor />
<div className="flex-auto graphiql-response min-h-[200px] p-2 mt-2 bg-slate-100 rounded-lg">
<Loader />
<ResponseEditor />
</div>
</div>
</div>
) : null}
</div>
</GraphiQLProvider>
</GraphiQLProvider>
)
: null}
</div>
</div>
);
}
Expand Down
Loading

0 comments on commit b6788a6

Please sign in to comment.