Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: /docs/concepts/features-overview/ #725

Merged
merged 6 commits into from
May 22, 2024
Merged
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
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')}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
/>

</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.
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
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')}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
/>
</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')}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
/>

</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
/>
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved

<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.
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved

{/* 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")}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
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')}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
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
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
- `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')}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
/>

</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}
Yohe-Am marked this conversation as resolved.
Show resolved Hide resolved
<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