-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Adding REST API example * Add smoke test for rest-api example * Add changeset * Update select field config
- Loading branch information
Showing
13 changed files
with
695 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"@keystone-next/example-rest-api": major | ||
"@keystonejs/examples-smoke-tests": patch | ||
--- | ||
|
||
REST API example |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# @keystone-next/example-rest-api |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## Feature Example - Creating REST API endpoints | ||
|
||
This project demonstrates how to create REST endpoints by extending Keystone's express app and using the Query API to execute queries against the schema. | ||
|
||
## Instructions | ||
|
||
To run this project, clone the Keystone repository locally 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. | ||
|
||
To run the seed data script, pass the `--seed-data` flag when starting the app. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { config } from '@keystone-next/keystone'; | ||
import { lists } from './schema'; | ||
import { insertSeedData } from './seed-data'; | ||
import { getTasks } from './routes/tasks'; | ||
|
||
/* | ||
A quick note on types: normally if you're adding custom properties to your | ||
express request you'd extend the global Express namespace, but we're not | ||
doing that here because we're in the keystone monorepo; so we're casting | ||
the request and keystone context with `as` instead to keep this local. | ||
*/ | ||
|
||
export default config({ | ||
db: { | ||
provider: 'sqlite', | ||
url: process.env.DATABASE_URL || 'file:./keystone-example.db', | ||
async onConnect(context) { | ||
if (process.argv.includes('--seed-data')) { | ||
await insertSeedData(context); | ||
} | ||
}, | ||
}, | ||
server: { | ||
/* | ||
This is the main part of this example. Here we include a function that | ||
takes the express app Keystone created, and does two things: | ||
- Adds a middleware function that will run on requests matching our REST | ||
API routes, to get a keystone context on `req`. This means we don't | ||
need to put our route handlers in a closure and repeat it for each. | ||
- Adds a GET handler for tasks, which will query for tasks in the | ||
Keystone schema and return the results as JSON | ||
*/ | ||
extendExpressApp: (app, createContext) => { | ||
app.use('/rest', async (req, res, next) => { | ||
(req as any).context = await createContext(req, res); | ||
next(); | ||
}); | ||
app.get('/rest/tasks', getTasks); | ||
}, | ||
}, | ||
lists, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"name": "@keystone-next/example-rest-api", | ||
"version": "0.0.0", | ||
"private": true, | ||
"license": "MIT", | ||
"scripts": { | ||
"dev": "keystone-next dev", | ||
"start": "keystone-next start", | ||
"build": "keystone-next build", | ||
"seed-data": "keystone-next --seed-data" | ||
}, | ||
"dependencies": { | ||
"@keystone-next/keystone": "^25.0.0", | ||
"express": "^4.17.1" | ||
}, | ||
"devDependencies": { | ||
"typescript": "^4.4.3" | ||
}, | ||
"engines": { | ||
"node": "^12.20 || >= 14.13" | ||
}, | ||
"repository": "https://github.com/keystonejs/keystone/tree/master/examples/rest-api" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import type { Request, Response } from 'express'; | ||
import type { KeystoneContext } from '@keystone-next/keystone/types'; | ||
|
||
/* | ||
This example route handler gets all the tasks in the database and returns | ||
them as JSON data, emulating what you'd normally do in a REST API. | ||
More sophisticated API routes might accept query params to select fields, | ||
map more params to `where` arguments, add pagination support, etc. | ||
We're also demonstrating how you can query related data through the schema. | ||
*/ | ||
|
||
export async function getTasks(req: Request, res: Response) { | ||
// This was added by the context middleware in ../keystone.ts | ||
const context = (req as any).context as KeystoneContext; | ||
// Let's map the `complete` query param to a where filter | ||
let isComplete; | ||
if (req.query.complete === 'true') { | ||
isComplete = { equals: true }; | ||
} else if (req.query.complete === 'false') { | ||
isComplete = { equals: false }; | ||
} | ||
// Now we can use it to query the Keystone Schema | ||
const users = await context.query.Task.findMany({ | ||
where: { | ||
isComplete, | ||
}, | ||
query: ` | ||
id | ||
label | ||
priority | ||
isComplete | ||
assignedTo { | ||
id | ||
name | ||
} | ||
`, | ||
}); | ||
// And return the result as JSON | ||
res.json(users); | ||
} |
Oops, something went wrong.