2017-11-30 22:11:43 +02:00
|
|
|
## Grapher as an API
|
|
|
|
|
2017-12-01 12:30:09 +02:00
|
|
|
If you like Grapher, or if `like` is an understatement, you can use it in any other language/medium.
|
|
|
|
|
2017-12-01 12:58:36 +02:00
|
|
|
You can expose it as an `HTTP API`, or via `DDP` (as a meteor method) for example, because
|
2017-12-01 12:30:09 +02:00
|
|
|
in React Native you have ways to connect to Meteor with:
|
2017-11-30 22:11:43 +02:00
|
|
|
|
|
|
|
https://www.npmjs.com/package/react-native-meteor#meteor-collections
|
|
|
|
|
2017-12-01 12:30:09 +02:00
|
|
|
Basically what Grapher needs to properly execute is the query, and you can make use of the firewalls easily,
|
|
|
|
but you need to manually handle authorization yourself.
|
2017-11-30 22:11:43 +02:00
|
|
|
|
|
|
|
### Exposing an HTTP API
|
|
|
|
|
|
|
|
```js
|
|
|
|
// This is how you can create a sample endpoint
|
|
|
|
|
|
|
|
import {createQuery} from 'meteor/cultofcoders:grapher';
|
|
|
|
import Picker from 'meteor/meteorhacks:picker';
|
|
|
|
import {EJSON} from 'meteor/ejson';
|
|
|
|
import {Meteor} from 'meteor/meteor';
|
|
|
|
import bodyParser from 'body-parser';
|
|
|
|
|
|
|
|
const grapherRoutes = Picker.filter(function () {
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
grapherRoutes.middleware(bodyParser.raw({
|
|
|
|
'type': 'application/ejson',
|
|
|
|
}));
|
|
|
|
|
|
|
|
grapherRoutes.route('/grapher', function (req, res) {
|
|
|
|
const body = req.body.toString();
|
|
|
|
const data = EJSON.parse(body);
|
|
|
|
|
|
|
|
// lets say this is a named query that looks like
|
2017-12-01 12:30:09 +02:00
|
|
|
const {query} = data; // query = {userList: params}
|
2017-11-30 22:11:43 +02:00
|
|
|
|
|
|
|
// authorize the user somehow
|
|
|
|
// it's up to you to extract an userId
|
|
|
|
// or something else that you use for authorization
|
|
|
|
|
|
|
|
const actualQuery = createQuery(query);
|
|
|
|
|
|
|
|
// if it's not a named query and the collection is not exposed, don't allow it.
|
2017-12-01 12:30:09 +02:00
|
|
|
// if you don't put this snippet of code, people will be able to do { users: { services: 1 } } types of queries.
|
|
|
|
// this is related to global queries.
|
2017-11-30 22:11:43 +02:00
|
|
|
if (actualQuery.isGlobalQuery && !actualQuery.collection.__isExposedForGrapher) {
|
|
|
|
throw new Meteor.Error('not-allowed');
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
const data = actualQuery.fetch({
|
|
|
|
// the userId (User Identification) that hits the firewalls
|
2017-12-01 12:58:36 +02:00
|
|
|
// user id can be anything, an API KEY, an Object, you and your firewalls decide
|
|
|
|
userId: 'XXX',
|
|
|
|
// you can specify other fields, because this is the context of the firewall
|
|
|
|
// whatever you define here, it can be accessed with `this`
|
2017-11-30 22:11:43 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
res.statusCode = 200;
|
|
|
|
res.end(EJSON.stringify({
|
|
|
|
data,
|
|
|
|
}));
|
|
|
|
} catch (e) {
|
|
|
|
res.statusCode = 500;
|
|
|
|
res.end(EJSON.stringify({
|
|
|
|
error: e.reason,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
2017-12-01 12:30:09 +02:00
|
|
|
Now you can do HTTP requests of `Content-Type: application/ejson` to http://meteor-server/grapher and retrieve data,
|
|
|
|
in EJSON format. If `EJSON` is not available in your language, you can parse it with `JSON` as well.
|
|
|
|
|
|
|
|
If you are in the JavaScript world: https://www.npmjs.com/package/ejson
|
2017-11-30 22:11:43 +02:00
|
|
|
|
2017-12-01 12:58:36 +02:00
|
|
|
If you want to use Meteor's Methods as an `HTTP API` to also handle mutations,
|
|
|
|
take a look here: https://github.com/cult-of-coders/fusion
|
2017-11-30 22:11:43 +02:00
|
|
|
|
|
|
|
And more closely: https://github.com/cult-of-coders/fusion/blob/7ec5cd50c3a471c0bdd65c9fa482124c149dc243/fusion/server/route.js
|
|
|
|
|
|
|
|
### Exposing a DDP Method
|
2017-12-01 12:30:09 +02:00
|
|
|
|
|
|
|
If you are connected to Meteor by DDP, using any DDP Client:
|
|
|
|
|
|
|
|
- React Native: https://www.npmjs.com/package/react-native-meteor
|
|
|
|
- JS: https://www.npmjs.com/package/ddp-client
|
|
|
|
- PHP: https://github.com/zyzo/meteor-ddp-php
|
|
|
|
- Python: https://github.com/hharnisc/python-ddp
|
|
|
|
- Ruby: https://github.com/tmeasday/ruby-ddp-client
|
|
|
|
|
2017-11-30 22:11:43 +02:00
|
|
|
```js
|
|
|
|
import {createQuery} from 'meteor/cultofcoders:grapher';
|
|
|
|
|
|
|
|
Meteor.methods({
|
|
|
|
'grapher'(query) {
|
|
|
|
const actualQuery = createQuery(query);
|
|
|
|
|
|
|
|
if (actualQuery.isGlobalQuery && !actualQuery.collection.__isExposedForGrapher) {
|
|
|
|
throw new Meteor.Error('not-allowed');
|
|
|
|
}
|
|
|
|
|
|
|
|
return actualQuery.fetch({
|
|
|
|
userId: this.userId,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
```
|
|
|
|
|
2017-12-01 12:58:36 +02:00
|
|
|
## Conclusion
|
2017-11-30 22:11:43 +02:00
|
|
|
|
|
|
|
Nothing stops you from using Grapher outside Meteor!
|
2017-12-01 12:30:09 +02:00
|
|
|
|
2017-12-01 12:58:36 +02:00
|
|
|
## [Continue Reading](api.md) or [Back to Table of Contents](index.md)
|