Skip to content

Commit

Permalink
docs(website): cleanup (#521)
Browse files Browse the repository at this point in the history
<!--
Pull requests are squash merged using:
- their title as the commit message
- their description as the commit body

Having a good title and description is important for the users to get
readable changelog and understand when they need to update his code and
how.
-->

### Describe your change

This mainly shuffles around the existing docs for better structure.
Still a lot to be done. The following pages are also empty as I lack the
info regarding their topics:
- Architecture
- Query engine

Super open to feedback. Bring up any points that you think should be
mentioned on each page and I'll add them.

Todo:
- [ ] Find a way to get webpack to ignore ts files
-
[Possible](https://dwf.dev/blog/2022/11/12/2022/updating-docusaurus-webpack-config)
way fwd.
- [ ] Reference section for all the meta-cli commands/flags


<!-- Explain WHAT the change is -->

### Motivation and context

Improve experience of new users.
<!-- Explain WHY the was made or link an issue number -->

### Migration notes

<!-- Explain HOW users should update their code when required -->

### Checklist

- [ ] The change come with new or modified tests
- [ ] Hard-to-understand functions have explanatory comments
- [ ] End-user documentation is updated to reflect the change
  • Loading branch information
Yohe-Am authored Feb 5, 2024
1 parent 392435a commit 6925110
Show file tree
Hide file tree
Showing 42 changed files with 1,427 additions and 1,399 deletions.
11 changes: 10 additions & 1 deletion examples/typegraphs/files-upload.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from typegraph import typegraph, Policy, t, Graph
from typegraph.providers.aws import S3Runtime

# skip-next-line
from typegraph.graph.params import Cors

@typegraph()

@typegraph(
# skip-next-line
cors=Cors(allow_origin=["https://metatype.dev", "http://localhost:3000"]),
)
def retrend(g: Graph):
public = Policy.public()

s3 = S3Runtime(
# we provide the name of the env vars
# the typegate will read from
"S3_HOST",
"S3_REGION",
"S3_ACCESS_KEY",
Expand All @@ -15,6 +23,7 @@ def retrend(g: Graph):
)

g.expose(
# we can then generate helpers for interacting with our runtime
listObjects=s3.list("bucket"),
getDownloadUrl=s3.presign_get("bucket"),
signUploadUrl=s3.presign_put("bucket"),
Expand Down
26 changes: 16 additions & 10 deletions examples/typegraphs/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,38 @@

@typegraph()
def math(g: Graph):
public = Policy.public()

# we need a runtime to run the functions on
deno = DenoRuntime()

public = Policy.public()
# we can provide the function code inline
random_item_fn = "({ items }) => items[Math.floor(Math.random() * items.length)]"

# or we can point to a local file that's accessible to the meta-cli
fib_module = "scripts/fib.ts"

# the policy implementation is based on functions itself
restrict_referer = deno.policy(
"restrict_referer_policy",
'(_, context) => context["headers"]["referer"] && new URL(context["headers"]["referer"]).pathname === "/math"',
)

random_item_fn = "({ items }) => items[Math.floor(Math.random() * items.length)]"

g.expose(
fib=deno.import_(
t.struct({"size": t.integer()}),
t.list(t.float()),
module="scripts/fib.ts",
name="default",
module=fib_module,
name="default", # name the exported function to run
).with_policy(restrict_referer),
random=deno.func(
t.struct(),
t.float(),
code="() => Math.random()",
).with_policy(public),
randomItem=deno.func(
t.struct({"items": t.list(t.string())}),
t.string(),
code=random_item_fn,
).with_policy(public),
random=deno.func(
t.struct(),
t.float(),
code="() => Math.random()", # more inline code
).with_policy(public),
)
17 changes: 13 additions & 4 deletions examples/typegraphs/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,37 @@ import { DenoRuntime } from "@typegraph/sdk/runtimes/deno.js";
typegraph({
name: "math",
}, (g) => {
// we need a runtime to run the functions on
const deno = new DenoRuntime();

const pub = Policy.public();

// we can provide the function code inline
const random_item_fn =
"({ items }) => items[Math.floor(Math.random() * items.length)]";

// the policy implementation is based on functions itself
const restrict_referer = deno.policy(
"restrict_referer_policy",
'(_, context) => context["headers"]["referer"] && new URL(context["headers"]["referer"]).pathname === "/math"',
);

const random_item_fn =
"({ items }) => items[Math.floor(Math.random() * items.length)]";
// or we can point to a local file that's accessible to the meta-cli
const fib_module = "scripts/fib.ts";

g.expose({
fib: deno.import(
t.struct({ "size": t.integer() }),
t.list(t.float()),
{ module: "scripts/fib.ts", name: "default" },
{
module: fib_module,
name: "default", // name the exported function to run
},
).withPolicy(restrict_referer),
random: deno.func(
t.struct({}),
t.float(),
{ code: "() => Math.random()" },
{ code: "() => Math.random()" }, // more inline code
).withPolicy(pub),
randomItem: deno.func(
t.struct({ "items": t.list(t.string()) }),
Expand Down
3 changes: 1 addition & 2 deletions examples/typegraphs/random.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from typegraph import typegraph, t, Graph
from typegraph import typegraph, Policy, t, Graph
from typegraph.runtimes.random import RandomRuntime
from typegraph.graph.params import Cors
from typegraph.policy import Policy


@typegraph(
Expand Down
6 changes: 6 additions & 0 deletions examples/typegraphs/roadmap-policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def roadmap(g: Graph):
db = PrismaRuntime("db", "POSTGRES")
deno = DenoRuntime()

# skip:start
bucket = t.struct(
{
# auto generate ids during creation
Expand Down Expand Up @@ -47,16 +48,21 @@ def roadmap(g: Graph):
},
name="vote",
)
# skip:end

# highlight-next-line
g.auth(Auth.basic(["andim"]))

# highlight-start
admins = deno.policy(
"admins",
"(_args, { context }) => !!context.username",
)
# highlight-end

g.expose(
pub,
# highlight-next-line
create_bucket=db.create(bucket).with_policy(admins),
get_buckets=db.find_many(bucket),
get_idea=db.find_many(idea),
Expand Down
4 changes: 2 additions & 2 deletions website/blog/2023-06-18-programmable-glue/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ We are introducing Metatype, a new project that allows developers to build modul

## What is Metatype?

<Metatype />
<Metatype />

## What are virtual graphs?

Expand All @@ -29,7 +29,7 @@ These elements can then be combined and composed together similarly on how you w

Before Metatype, there was a gap in the technological landscape for a solution that specifically addressed the transactional, short-lived use cases. While there were existing tools for analytical or long-running use cases, such as Trino and Temporal, there was no generic engine for handling transactional, short-lived tasks.

<CompareLandscape />
<CompareLandscape />

## Give it a try!

Expand Down
4 changes: 4 additions & 0 deletions website/docs/concepts/access-control/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ sidebar_position: 5
---

# Access control

Typegraphs allow you to specify granular access control when exposing your materializers.
This can be done at the materializer or the type field level.
[Policy-based-access-control](https://csrc.nist.gov/glossary/term/policy_based_access_control) is the primary paradigm [implemented](/docs/reference/policies) in Metatype today.
51 changes: 33 additions & 18 deletions website/docs/concepts/features-overview/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,53 @@ sidebar_position: 1

# Features overview

## Authentication
- Metatype offers multiple runtimes with pre-defined operations (e.g. Prisma) and can replace the needs for an ad-hoc backend.

## GraphQL and REST queries
- When the project grows, you can easily introduce new APIs or break existing ones in smaller parts while keeping the same interface.

## Type checking
- You can write complex business logic directly in Typescript, Python or WebAssembly and run them directly inside the query engine.

## Live reload during development
- Most of the frontend are today built on composable components, this brings a similar approach to backend development.

## Built-in CORS and rate-limiting
- Third-parties APIs can be easily integrated, providing you visibility and control over them.

## Policy-based authorization
- Metatype is interoperable with existing systems, and can be introduced step by step.

## Bring your own storage
- Metatype can be easily self-hosted or customized according to your needs.

s3

## Function runner
## GraphQL and REST queries

python, typescript
Easily expose business logic endpoints through using generated [GraphQl APIs](/docs/reference/runtimes/graphql).
Including helpers to auto-generate and expose CRUD operations from your types on [myriad of databases](/docs/reference/runtimes/prisma).
These are only helpers though.
They're built upon the typegraphs primitive that compose well with every other feature and allow [granular control](/docs/reference/types/reducers) when required.
There are helpers to expose sections of your GraphQl through [REST queries as well](/docs/guides/rest).

## Automatic migration
## Authentication

it offers multiple runtimes [1] with pre-defined operations (e.g. Prisma) and can replace the needs for an ad-hoc backend
First class support for authentication primitives through the Policies object.
Oauth2 helpers for popular services included as well.
Read more [here](/docs/reference/typegate/authentication).

- when the project grows, you can easily introduce new APIs or break existing ones in smaller parts while keeping the same interface
## Type checking

Everything in Metatype starts with [types](/docs/reference/types).
The typegraph sdks allow you to model exactly what's needed for your app with simple syntax and a modern type system.
Type authoring isn't done with through static, declarative snippets but through the typegraphs in a functional, "first class" manner allowing you build your own abstractions when needed.

## Live reload during development

- you can write complex business logic directly in Typescript, Python or WebAssembly and run them directly inside the query engine
Metatype development is primarily done through the [meta-cil](/docs/reference/meta-cli) that's designed to get you up and productive in no time.
Live auto-reload, database migration management, type-checking and linting, it's all there.

- most of the frontend are today built on composable components, this brings a similar approach to backend development
## Built-in CORS and rate-limiting

## Bring your own storage

- third-parties APIs can be easily integrated, providing you visibility and control over them
Working with object files in Metatype is easy using the [S3Runtime](/docs/reference/runtimes/s3) including support for [GraphQl file uploads](/docs/guides/files-upload) and presigned URLs.

- it is interoperable with existing systems, and can be introduced step by step
## Function runner

- it can be easily self-hosted or customized according to your needs
When the expressive powers of the typegate primitives are not up for the task, different runtimes are available for running the exact, turing complete, code you need.
Metatype supports [Typescript](/docs/reference/runtimes/deno), [Python](/docs/reference/runtimes/python) and [Wasm](/docs/reference/runtimes/wasmedge) functions today.
10 changes: 5 additions & 5 deletions website/docs/concepts/mental-model/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Metatype from "../../../shared/metatype-intro.mdx";
This page gives a high-level view of Metatype's foundations.

:::tip Looking to build?
For a hands-on introduction, head over to the [metatype basics page](/docs/tutorials/metatype-basics) and start build your first typegraph.
For a hands-on introduction, head over to the [basics tutorial](/docs/tutorials/metatype-basics) and start build your first typegraph.
:::

## Why does Metatype exist?
Expand Down Expand Up @@ -48,17 +48,17 @@ This computing model brings numerous advantages:

## What's exactly Metatype?

<Metatype />
<Metatype />

### Architectural overview

Metatype is designed for cloud environments and comes with minimal components. The only requirement to scale horizontally is to share some memory between replicas via Redis. You can use Metatype [helm chart](https://github.com/metatypedev/charts) to directly deploy typegates on your Kubernetes cluster.

<div className="text-center">
<div className="text-center">

![Metatype's architecture](image.drawio.svg)

</div>

</div>

import CodeBlock from "@theme/CodeBlock";
import MiniQL from "@site/src/components/MiniQL";
Expand Down
32 changes: 9 additions & 23 deletions website/docs/guides/external-functions/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,17 @@ import CodeBlock from "@theme-original/CodeBlock";

# Run serverless functions

{/* ## Embedded runner
## Embedded runner
## External runner */}

Typegraphs allow us to define and execute at different places to accomplish myriad of tasks:

## External runner
<TGExample typegraph="math"
python={require("../../../../examples/typegraphs/math.py")}
query={require('./math.graphql')}
/>

## Typegraph
<CodeBlock language="python">{require("../../../../examples/typegraphs/math.py").content}</CodeBlock>
Here's what `fib.ts` looks like:

## External function definition
<!-- <CodeBlock language="typescript">{require("../../../../examples/typegraphs/scripts/fib.ts").content}</CodeBlock> -->

```typescript
// scripts/fib.ts
const CACHE = [1, 1];
const MAX_CACHE_SIZE = 1000;

export default function fib({ size }: { size: number }) {
if (size > MAX_CACHE_SIZE) {
throw new Error(`unsupported size ${size} > ${MAX_CACHE_SIZE}`);
}
let i = CACHE.length;
while (i++ < size) {
CACHE.push(CACHE[i - 2] + CACHE[i - 3]);
}
return CACHE.slice(0, size);
}
```
<CodeBlock language="typescript">{require("!!code-loader!../../../../examples/typegraphs/scripts/fib.ts").content}</CodeBlock>
13 changes: 13 additions & 0 deletions website/docs/guides/external-functions/math.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
fib(size: 50)
random
randomItem(
items: [
"ice",
"advice",
"gold",
"flowers",
"dirt"
]
)
}
19 changes: 5 additions & 14 deletions website/docs/guides/files-upload/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,15 @@
sidebar_position: 50
---

import TGExample from "@site/src/components/TGExample";
import CodeBlock from "@theme-original/CodeBlock";
import S3Intro from "@site/shared/s3/index.mdx";

# Upload files to cloud storage

## Typegraph
<S3Intro />

```ini
TG_RETREND_S3_HOST=http://localhost:9000
TG_RETREND_S3_REGION=local
TG_RETREND_S3_ACCESS_KEY=minio
TG_RETREND_S3_SECRET_KEY=password
TG_RETREND_S3_PATH_STYLE=true
```

<CodeBlock language="python">{require("../../../../examples/typegraphs/files-upload.py").content}</CodeBlock>
We can then use this typegraph from our client code like so:

## Uploading file using presigned url
### Uploading file using presigned url

```ts
const image = await Deno.readFile("website/static/images/logo.png");
Expand Down Expand Up @@ -54,7 +45,7 @@ const upload = await fetch(presigned, {
console.log(upload.status);
```

## Uploading file using GraphQL multipart request
### Uploading file using GraphQL multipart request

Metatype supports
[GraphQL multipart request](https://github.com/jaydenseric/graphql-multipart-request-spec)
Expand Down
Loading

0 comments on commit 6925110

Please sign in to comment.