-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(extension/transport-memory): config ctx (#1312)
- Loading branch information
1 parent
d52e7ab
commit 23ced13
Showing
23 changed files
with
674 additions
and
216 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
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 |
---|---|---|
@@ -1,33 +1,138 @@ | ||
/** | ||
* This example shows how you can send requests against an in-memory GraphQL schema instead of one hosted over HTTP. | ||
* | ||
* Imagine this example as server code that receives HTTP requests and internally fulfills them with requests to a GraphQL schema. | ||
* | ||
* Included here is how to work with Graffle's lightweight client-forking model to create a request-scoped Graffle client. | ||
* By having a Graffle instance per request, the context value that the GraphQL resolvers get during execution can reflect | ||
* the user making the request. | ||
*/ | ||
|
||
import { Graffle } from 'graffle' | ||
import { TransportMemory } from 'graffle/extensions/transport-memory' | ||
import { GraphQLObjectType, GraphQLSchema, GraphQLString } from 'graphql' | ||
import { showJson } from '../$/helpers.js' | ||
|
||
interface Context { | ||
database: DatabaseClient | ||
user: RequestingUser | ||
} | ||
|
||
interface RequestingUser { | ||
id: string | ||
} | ||
|
||
interface DatabaseClient { | ||
account: { | ||
findUnique: (parameters: { where: { ownerId: string } }) => DatabaseModelAccount | undefined | ||
} | ||
user: { | ||
findUnique: (parameters: { where: { id: string } }) => DatabaseModelUser | undefined | ||
} | ||
} | ||
|
||
interface DatabaseModelUser { | ||
id: string | ||
name: string | ||
} | ||
|
||
interface DatabaseModelAccount { | ||
id: string | ||
ownerId: string | ||
} | ||
|
||
const databaseData = { | ||
accounts: [{ | ||
id: `account_abc123`, | ||
ownerId: `user_abc123`, | ||
}], | ||
users: [{ | ||
id: `user_abc123`, | ||
name: `Kenya Hara`, | ||
}], | ||
} | ||
|
||
const DatabaseClient = { | ||
create: (): DatabaseClient => { | ||
return { | ||
account: { | ||
findUnique: (parameters: { where: { ownerId: string } }) => | ||
databaseData.accounts.find((account) => account.ownerId === parameters.where.ownerId), | ||
}, | ||
user: { | ||
findUnique: (parameters: { where: { id: string } }) => | ||
databaseData.users.find((user) => user.id === parameters.where.id), | ||
}, | ||
} | ||
}, | ||
} | ||
|
||
const schema = new GraphQLSchema({ | ||
query: new GraphQLObjectType({ | ||
name: `Query`, | ||
fields: { | ||
foo: { | ||
account: { | ||
type: GraphQLString, | ||
resolve: () => `bar`, | ||
resolve: (_, __, context: Context) => { | ||
const account = context.database.account.findUnique({ where: { ownerId: context.user.id } }) | ||
if (!account) throw new Error(`Account not found.`) | ||
return account.id | ||
}, | ||
}, | ||
}, | ||
}), | ||
}) | ||
|
||
const graffle = Graffle | ||
interface Token { | ||
userId: string | ||
} | ||
|
||
const getAndValidateToken = (request: Request): Token => { | ||
const tokenEncoded = request.headers.get(`authorization`)?.match(/^Bearer\s+(.+)$/)?.[1] | ||
if (!tokenEncoded) throw new Error(`No token provided.`) | ||
// ... decode token securely ... | ||
return { | ||
userId: tokenEncoded, | ||
} | ||
} | ||
|
||
const database = DatabaseClient.create() | ||
|
||
const baseGraffle = Graffle | ||
.create() | ||
.use(TransportMemory({ schema })) | ||
.transport(`memory`) | ||
|
||
const data = await graffle.gql` | ||
{ | ||
foo | ||
const handleRequest = async (request: Request) => { | ||
const user = { | ||
id: getAndValidateToken(request).userId, | ||
} | ||
|
||
const resolverContextValue = { | ||
database, | ||
user, | ||
} | ||
`.send() | ||
|
||
showJson(data) | ||
// Create a copy of Graffle with transport configured | ||
// with context data particular to this request. | ||
const requestScopedGraffle = baseGraffle.transport({ | ||
resolverValues: { | ||
context: resolverContextValue, | ||
}, | ||
}) | ||
|
||
const data = await requestScopedGraffle.gql` | ||
{ | ||
account | ||
} | ||
`.send() | ||
|
||
showJson(data) | ||
} | ||
|
||
// Server receives a request... | ||
await handleRequest( | ||
new Request(`https://foo.com`, { | ||
headers: new Headers({ authorization: `Bearer user_abc123` }), | ||
}), | ||
) |
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
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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
---------------------------------------- SHOW ---------------------------------------- | ||
{ | ||
"foo": "bar" | ||
"account": "account_abc123" | ||
} |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.