Skip to content

Commit

Permalink
Add documentation for getContext (#7997)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Cousens <dcousens@users.noreply.github.com>
  • Loading branch information
dcousens and dcousens committed Oct 12, 2022
1 parent 8c083ed commit 065695a
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 26 deletions.
1 change: 1 addition & 0 deletions docs/components/docs/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export function DocsNavigation() {

<NavSection title="Context">
<NavItem href="/docs/context/overview">Overview</NavItem>
<NavItem href="/docs/context/get-context">getContext</NavItem>
<NavItem href="/docs/context/query">Query</NavItem>
<NavItem href="/docs/context/db-items">DB</NavItem>
</NavSection>
Expand Down
57 changes: 57 additions & 0 deletions docs/pages/docs/context/get-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: "Get Context"
description: "getContext is a function exported by @keystone-6/core/context to support operations without starting a HTTP server"
---

Keystone's command line interface is helpful, but sometimes you don't want to startup the HTTP server, or kickoff any build processes.
Maybe you need to insert data into the database, maybe you want to use Keystone with a custom protocol or a tiny REST API.
*Or maybe you want to write unit tests.*

If you have previously run `keystone build` or `keystone dev`, then you can use `getContext`.
If you change your configuration, you should [rebuild your project](../guides/cli) before using `getContext`.

Using the `getContext` function does not use the typical Keystone entry point - it is a function and only requires that your Prisma client has been built and can be provided as a parameter with your Keystone configuration.

```typescript
import { getContext } from '@keystone-6/core/context';
import config from './keystone';
import * as PrismaModule from '.prisma/client';

const context = getContext(config, PrismaModule);

// ... whatever you need
```

{% hint kind="tip" %}
For inspiration, see [the script example project](https://github.com/keystonejs/keystone/tree/main/examples/script-field), and how we use [`tsx`](https://github.com/esbuild-kit/tsx) to seed the database with some data.
{% /hint %}

A context created in this way does not have an implicit `session`, nor is it a `sudo()` context.
For more information about how to use a context, please see the [overview](./overview).

{% hint kind="warn" %}
The `context` returned from `getContext` is not a global - every time you instantiate it, you are instantiating a Prisma Client.
Without careful usage, you may encounter the warnings that there are too many instances of your Prisma Client.
{% /hint %}

## Related resources

{% related-content %}
{% well
heading="Example Project: Script"
href="https://github.com/keystonejs/keystone/tree/main/examples/script"
target="_blank" %}
Shows you how to write tests against the GraphQL API to your Keystone system. Builds on the Authentication example project.
Shows you how to write code to interact with Keystone without using the standard `@keystone-6/core/scripts/cli` tools.
{% /well %}
{% well
heading="Query API Reference"
href="/docs/context/query" %}
A programmatic API for running CRUD operations against your GraphQL API. For each list in your system you get an API at `context.query.<listName>`.
{% /well %}
{% well
heading="Context API Reference"
href="/docs/context/overview" %}
The API for run-time functionality in your Keystone system. Use it to write business logic for access control, hooks, testing, GraphQL schema extensions, and more.
{% /well %}
{% /related-content %}
22 changes: 11 additions & 11 deletions docs/pages/docs/context/overview.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
title: "Context Overview"
description: "The KeystoneContext object is the primary API entry point for all of the run-time functionality of your system. It's APIs can be used to write things like access control, hooks, testing and GraphQL schema extensions."
description: "The Context object is the primary API entry point for all of the run-time functionality of your system. It's APIs can be used to write things like access control, hooks, testing and GraphQL schema extensions."
---

The `KeystoneContext` object is the primary API entry point for all of the run-time functionality of your Keystone system.
The `Context` object is the primary API entry point for all of the run-time functionality of your Keystone system.
In GraphQL, a [`context`](https://graphql.org/learn/execution/#root-fields-resolvers) is a value which is provided to every resolver and holds important contextual information such as the currently logged in user, or access to a database.
Keystone makes a `KeystoneContext` object available as the context of all resolvers in the system.
The APIs provided by the `KeystoneContext` object can be used to write the business logic for things like [access control](../guides/auth-and-access-control), [hooks](../guides/hooks), [testing](../guides/testing) and GraphQL [schema extensions](../guides/schema-extension).
Keystone makes a `Context` object available as the context of all resolvers in the system.
The APIs provided by the `Context` object can be used to write the business logic for things like [access control](../guides/auth-and-access-control), [hooks](../guides/hooks), [testing](../guides/testing) and GraphQL [schema extensions](../guides/schema-extension).

The `KeystoneContext` object has the following properties, which are documented below.
The `Context` object has the following properties, which are documented below.

```typescript
import type { KeystoneContext } from '@keystone-6/core/types';
import type { Context } from '.keystone/types';

context = {
// HTTP request object
Expand Down Expand Up @@ -100,17 +100,17 @@ See the [session API](../config/session#session-context) for more details.
### New context creators

When using the `context.query`, `context.graphql.run`, and `context.graphql.raw` APIs, access control and session information is passed through to these calls from the `context` object.
The following functions will create a new `KeystoneContext` object with this behaviour modified.
The following functions will create a new `Context` object with this behaviour modified.

`sudo()`: A function which returns a new `KeystoneContext` object with all access control disabled and all filters enabled for subsequent API calls.
`sudo()`: A function which returns a new `Context` object with all access control disabled and all filters enabled for subsequent API calls.

`exitSudo()`: A function which returns a new `KeystoneContext` object with all access control re-enabled for subsequent API calls.
`exitSudo()`: A function which returns a new `Context` object with all access control re-enabled for subsequent API calls.

`withSession(newSession)`: A function which returns a new `KeystoneContext` object with the `.session` object replaced with `newSession`.
`withSession(newSession)`: A function which returns a new `Context` object with the `.session` object replaced with `newSession`.

### Database access

The `KeystoneContext` object exposes the underlying database driver directly via `context.prisma`, which is a [Prisma Client](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference) object.
The `Context` object exposes the underlying database driver directly via `context.prisma`, which is a [Prisma Client](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference) object.

### Images API

Expand Down
5 changes: 2 additions & 3 deletions docs/pages/docs/guides/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,8 @@ beforeEach(async () => {

const context = getContext(config, PrismaModule);


test('Keystone test', async () => {
// Write your test here using `context`
test('Your unit test', async () => {
// ...
});
```

Expand Down
35 changes: 24 additions & 11 deletions docs/pages/docs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,6 @@ export default function Docs() {
gap: 'var(--space-xlarge)',
})}
>
<Well
grad="grad2"
heading="Keystone 5 vs Next. Which should you use?"
href="/updates/keystone-5-vs-keystone-6-preview"
>
We’re graduating Keystone 6 soon. If you’re wondering which version to start a new project
with today, this guide is for you.
</Well>
<Well grad="grad2" heading="Command line foundations" href="/docs/guides/cli">
Keystone’s CLI helps you develop, build, and deploy projects. This guide explains all you
need to standup a new backend in the terminal.
Expand All @@ -284,14 +276,35 @@ export default function Docs() {
Query filters are an integral part of Keystone’s powerful GraphQL APIs. This guide will
show you how to use filters to get the data you need from your system.
</Well>
<Well grad="grad2" heading="Understanding Hooks" href="/docs/guides/hooks">
Learn how to use Hooks within your schema to extend Keystone’s powerful CRUD GraphQL APIs
with your own business logic.
</Well>
<Well grad="grad2" heading="How To Use Document Fields" href="/docs/guides/document-fields">
Keystone’s document field is a highly customisable rich text editor that stores content as
structured JSON. Learn how to configure it and incorporate your own custom React
components.
</Well>
<Well grad="grad2" heading="Understanding Hooks" href="/docs/guides/hooks">
Learn how to use Hooks within your schema to extend Keystone’s powerful CRUD GraphQL APIs
with your own business logic.
<Well grad="grad2" heading="Document Field Demo" href="/docs/guides/document-field-demo">
Test drive the many features of Keystone’s Document field on this website.
</Well>
<Well grad="grad2" heading="Custom Fields" href="/docs/guides/custom-fields">
Learn how to define your own custom field types in Keystone, with customisable backend
data structure, and Admin UI appearance.
</Well>
<Well grad="grad2" heading="Testing Guide" href="/docs/guides/testing">
Learn how to test the behaviour of your Keystone system to ensure it does what you expect.
</Well>
<Well grad="grad2" heading="Virtual fields" href="/docs/guides/virtual-fields">
Virtual fields offer a powerful way to extend your GraphQL API. This guide introduces the
syntax and shows you how start simply and end up with a complex result.
</Well>
<Well grad="grad2" heading="Choosing a Database" href="/docs/guides/choosing-a-database">
Keystone supports Postgres, MySQL and SQLite. This guide explains how to choose the best
for your project.
</Well>
<Well grad="grad2" heading="Images and Files" href="/docs/guides/images-and-files">
Learn how to store and manage Images and Files in Keystone.
</Well>
</div>

Expand Down
2 changes: 1 addition & 1 deletion examples/limits/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This example includes sample data. To add it to your database:

## Try it out in CodeSandbox 🧪

You can play with this example online in a web browser using the free [codesandbox.io](https://codesandbox.io/) service. To launch this example, open the URL <https://githubbox.com/keystonejs/keystone/tree/main/examples/blog>. You can also fork this sandbox to make your own changes.
You can play with this example online in a web browser using the free [codesandbox.io](https://codesandbox.io/) service. To launch this example, open the URL <https://githubbox.com/keystonejs/keystone/tree/main/examples/limits>. You can also fork this sandbox to make your own changes.

## Next steps

Expand Down
30 changes: 30 additions & 0 deletions examples/script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
## Base Project - Script

This project demonstrates how to write code to interact with Keystone without using the standard `@keystone-6/core/scripts/cli` tools.

The `getContext` function does not ahdere to the typical Keystone entry-point and requires that your Prisma schema has been previously built by Keystone.

## Instructions

To run this project, clone the Keystone repository locally, run `yarn` at the root of this repository, then navigate to this directory and run:

```shell
yarn dev
```

This will start the Admin UI at [localhost:3000](http://localhost:3000).
You can use the Admin UI to create items in your database.

You can also access a GraphQL Playground at [localhost:3000/api/graphql](http://localhost:3000/api/graphql), which allows you to directly run GraphQL queries and mutations.

Congratulations, you're now up and running with Keystone! 🚀

## Try it out in CodeSandbox 🧪

You can play with this example online in a web browser using the free [codesandbox.io](https://codesandbox.io/) service. To launch this example, open the URL <https://githubbox.com/keystonejs/keystone/tree/main/examples/script>. You can also fork this sandbox to make your own changes.

## Next steps

Experiment with the code in this example to see how Keystone works, familiarise yourself with the Admin UI, and learn about the GraphQL Playground.

When you’ve got the hang of this base project, try a [feature project](../) to learn Keystone’s advanced features and take your knowledge to the next level.

1 comment on commit 065695a

@vercel
Copy link

@vercel vercel bot commented on 065695a Oct 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.