Skip to content

Commit 833f297

Browse files
authored
Merge pull request #6 from antstackio/example
add example
2 parents 1507d60 + 94c6c7d commit 833f297

File tree

1 file changed

+77
-12
lines changed

1 file changed

+77
-12
lines changed

example/index.ts

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,107 @@
1-
// import the library.. aaaaaaaaah
2-
import { defaultCipherList } from "constants";
3-
import createApp from "../src/index";
1+
/*
2+
* Let's imagine that there is a service that lets you build services that has graphql api for interaction.
3+
* But sadly the service doesn't offer you any way to implement anykind of RBAC (Role Based Access Control) on top of
4+
* it. You don't want every user (using your app?) having unrestricted access to the entire service, do you?
5+
* . Apparently then you have to put some kind of middleware that checks if the app user
6+
* has proper permissions and if so then proxy the request to the service.
7+
*
8+
* express-graphql-proxy library lets you do that by parsing the user queries and mutations into a javascript object
9+
* which can be used to validate the request.
10+
*/
411

5-
// handle fetching pokemons
6-
function pokemons() {
7-
return true;
8-
}
12+
// import the default function which can be used to create an express app
13+
import createApp from "@antstackio/express-graphql-proxy";
914

10-
// all the handlers
15+
// define handlers for each query/mutation type
1116
const handlers = {
12-
mutation: {},
1317
query: {
14-
pokemons,
18+
getTodo,
19+
getTodos,
20+
},
21+
mutation: {
22+
addTodo,
1523
},
1624
};
1725

26+
// handler "getTodo" query type
27+
// say user is making some query like --> becomes
28+
// ---------------------------------- ----------
29+
// query geTodo { {
30+
// getTodo(id: 111, userId: 435) { args: { id: 111, userId: 435 },
31+
// id selectedFields: {
32+
// task id: 1,
33+
// status task: 1,
34+
// } status: 1
35+
// } }
36+
// }
37+
function getTodo(args, selectedFields, context) {
38+
//arguments will have the arguments passed to the query
39+
40+
// only a user should be able to retreieve their todo
41+
if (!args.userId == context.user._id) {
42+
return false;
43+
}
44+
45+
return true;
46+
}
47+
48+
// handler "getTodo" query type
49+
function getTodos(args, selectedFields, { req, res, user }) {
50+
//arguments will have the arguments passed to the query
51+
52+
// only a user should be able to retreieve their todo
53+
// context also has req and res objects that are avaialable in express handlers.
54+
// they can be used to override the default behavior of the library
55+
if (!args.userId == user._id) {
56+
// sending a custom response
57+
return res.status(401).send("Unauthorized");
58+
}
59+
60+
return true;
61+
}
62+
63+
function addTodo(args, selectedFields, context) {
64+
if (args.userId == context.user._id) {
65+
return false;
66+
}
67+
return true;
68+
}
69+
1870
function handlerFunc(gqlObject, context) {
19-
//user deets received in header
71+
// imaginary user details that being send as header..
72+
// usually these are token, or auth cookies that needs to be parsed and validated
2073
const userId = context.req.headers.user;
2174
const admin = !!context.req.headers.admin;
2275

76+
// each req can have multiple queries or mutations inside hence
77+
// gqlObject will have queryObjects instead of single one.
78+
// Will have to iterate over each of them and decide if user has required permissions
2379
const result = gqlObject.queryObjects.every((item) =>
2480
// map the gqlObject to a suitable handler
2581
handlers[gqlObject.type][item.operationName](
2682
item.variables,
2783
item.selectedFields,
84+
// inject the parsed user deeets so its available in the handlers
2885
{ ...context, user: { _id: userId, admin } }
2986
)
3087
);
3188

89+
// if true then req is proxied, else responded with 401 Unauthorized
3290
return result;
3391
}
3492

93+
// create an express app
3594
const app = createApp(
36-
{ resourceUri: "https://graphql-pokemon2.vercel.app", headers: {} },
95+
{
96+
resourceUri: "https://my-app.imaginary-service.com/graphql",
97+
headers: {
98+
api_key: process.env.API_KEY,
99+
},
100+
},
37101
handlerFunc
38102
);
39103

104+
// listen on port 3000
40105
app.listen(3000, () => {
41106
console.log("app listening on port 3000");
42107
});

0 commit comments

Comments
 (0)