mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-14 17:02:49 +03:00
add nodejs 6 and python for serverless triggers on gcloud functions (#608)
This commit is contained in:
parent
f34338f792
commit
f40da07aaa
@ -6,8 +6,8 @@ Some of the language/platforms are work in progress. We welcome contributions fo
|
||||
|
||||
| Folder name | Use-case| Node.js(8) | Node.js(6) | Python
|
||||
|-------------|---------|:--------:|:------:|:----:
|
||||
| echo | echo the trigger payload | ✅ | ❌ | ❌
|
||||
| mutation | insert related data on an insert event using graphql mutation | ✅ | ❌ | ❌
|
||||
| echo | echo the trigger payload | ✅ | ✅ | ✅
|
||||
| mutation | insert related data on an insert event using graphql mutation | ✅ | ✅ | ❌
|
||||
| push-notification | send push notification on database event | ❌ | ❌ | ❌
|
||||
| etl | transform the trigger payload and update an algolia index | ❌ | ❌ | ❌
|
||||
|
||||
|
@ -0,0 +1,20 @@
|
||||
# This file specifies files that are *not* uploaded to Google Cloud Platform
|
||||
# using gcloud. It follows the same syntax as .gitignore, with the addition of
|
||||
# "#!include" directives (which insert the entries of the given .gitignore-style
|
||||
# file at that point).
|
||||
#
|
||||
# For more information, run:
|
||||
# $ gcloud topic gcloudignore
|
||||
#
|
||||
.gcloudignore
|
||||
# If you would like to upload your .git directory, .gitignore file or files
|
||||
# from your .gitignore file, remove the corresponding line
|
||||
# below:
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
node_modules
|
||||
|
||||
.env.yaml
|
||||
.prod.env.yaml
|
||||
|
2
community/boilerplates/serverless-triggers/google-cloud-functions/nodejs6/echo/.gitignore
vendored
Normal file
2
community/boilerplates/serverless-triggers/google-cloud-functions/nodejs6/echo/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.prod.env.yaml
|
@ -0,0 +1,40 @@
|
||||
# Setup table
|
||||
|
||||
Create the table using the console:
|
||||
|
||||
```
|
||||
Table name: profile
|
||||
|
||||
Columns:
|
||||
|
||||
id: Integer auto-increment
|
||||
name: Text
|
||||
address: Text
|
||||
lat: Numeric, Nullable
|
||||
lng: Numeric, Nullable
|
||||
```
|
||||
|
||||
# Deploy Google Cloud function
|
||||
|
||||
Deploy the function:
|
||||
|
||||
```bash
|
||||
gcloud beta functions deploy nodejs-echo \
|
||||
--trigger-http
|
||||
```
|
||||
|
||||
Get the trigger URL:
|
||||
```yaml
|
||||
httpsTrigger:
|
||||
url: https://us-central1-hasura-test.cloudfunctions.net/nodejs-echo
|
||||
```
|
||||
|
||||
Open Hasura console, goto `Events -> Add Trigger` and create a new trigger:
|
||||
```
|
||||
Trigger name: profile_change
|
||||
Schema/Table: public/profile
|
||||
Operations: Insert, Update, Delete
|
||||
Webhook URL: [Trigger URL]
|
||||
```
|
||||
|
||||
Once the trigger is created, goto `Data -> profile -> Insert row` and add a row.
|
@ -0,0 +1,6 @@
|
||||
exports.function = (req, res) => {
|
||||
const { event: {op, data}, table: {name, schema} } = req.body;
|
||||
const response = {message: 'received event', data: {op, data, name, schema}};
|
||||
console.log(response);
|
||||
res.json(response);
|
||||
};
|
@ -0,0 +1,2 @@
|
||||
GMAPS_API_KEY: '[GMAPS_API_KEY]'
|
||||
HASURA_GRAPHQL_ENGINE_URL: 'http://[HGE_IP]/v1alpha1/graphql'
|
@ -0,0 +1,19 @@
|
||||
# This file specifies files that are *not* uploaded to Google Cloud Platform
|
||||
# using gcloud. It follows the same syntax as .gitignore, with the addition of
|
||||
# "#!include" directives (which insert the entries of the given .gitignore-style
|
||||
# file at that point).
|
||||
#
|
||||
# For more information, run:
|
||||
# $ gcloud topic gcloudignore
|
||||
#
|
||||
.gcloudignore
|
||||
# If you would like to upload your .git directory, .gitignore file or files
|
||||
# from your .gitignore file, remove the corresponding line
|
||||
# below:
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
node_modules
|
||||
|
||||
.env.yaml
|
||||
.prod.env.yaml
|
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
.prod.env.yaml
|
@ -0,0 +1,71 @@
|
||||
# Setup table
|
||||
|
||||
Create the table using the console:
|
||||
|
||||
```
|
||||
Table name: profile
|
||||
|
||||
Columns:
|
||||
|
||||
id: Integer auto-increment
|
||||
name: Text
|
||||
address: Text
|
||||
lat: Numeric, Nullable
|
||||
lng: Numeric, Nullable
|
||||
```
|
||||
|
||||
# Deploy Google Cloud function
|
||||
|
||||
We are going to use Google Maps API in our cloud function.
|
||||
|
||||
Enable Google Maps API and get an API key (we'll call it `GMAPS_API_KEY`) following [this
|
||||
guide](https://developers.google.com/maps/documentation/geocoding/start?hl=el#auth)
|
||||
|
||||
Check the `Places` box to get access to Geocoding API.
|
||||
|
||||
We'll follow [this guide](https://cloud.google.com/functions/docs/quickstart)
|
||||
and create a Cloud Function with NodeJS 6.
|
||||
|
||||
```bash
|
||||
gcloud components update &&
|
||||
gcloud components install beta
|
||||
```
|
||||
|
||||
Goto the `cloudfunction` directory:
|
||||
|
||||
```bash
|
||||
cd cloudfunction
|
||||
```
|
||||
|
||||
Edit `.env.yaml` and add values for the following as shown:
|
||||
```yaml
|
||||
# .env.yaml
|
||||
GMAPS_API_KEY: '[GMAPS_API_KEY]'
|
||||
HASURA_GRAPHQL_ENGINE_URL: 'http://[HGE_IP]/v1alpha1/graphql'
|
||||
```
|
||||
|
||||
```bash
|
||||
gcloud beta functions deploy trigger \
|
||||
--runtime nodejs6 \
|
||||
--trigger-http \
|
||||
--region asia-south1 \
|
||||
--env-vars-file .env.yaml
|
||||
```
|
||||
|
||||
Get the trigger URL:
|
||||
```yaml
|
||||
httpsTrigger:
|
||||
url: https://asia-south1-hasura-test.cloudfunctions.net/trigger
|
||||
```
|
||||
|
||||
Goto `HGE_IP` on browser, `Events -> Add Trigger` and create a new trigger:
|
||||
```
|
||||
Trigger name: profile_change
|
||||
Schema/Table: public/profile
|
||||
Operations: Insert
|
||||
Webhook URL: [Trigger URL]
|
||||
```
|
||||
|
||||
Once the trigger is created, goto `Data -> profile -> Insert row` and add a new
|
||||
profile with name and address, save. Goto `Browse rows` tabs to see lat and lng
|
||||
updated, by the cloud function.
|
@ -0,0 +1,49 @@
|
||||
const fetch = require('node-fetch');
|
||||
const { query } = require('graphqurl');
|
||||
|
||||
const MUTATION_UPDATE_LAT_LONG = `
|
||||
mutation updateLatLong($id: Int!, $lat: numeric! $lng: numeric!) {
|
||||
update_profile(
|
||||
where: {id: {_eq: $id}},
|
||||
_set: {
|
||||
lat: $lat,
|
||||
lng: $lng
|
||||
}
|
||||
) {
|
||||
affected_rows
|
||||
returning {
|
||||
id
|
||||
lat
|
||||
lng
|
||||
}
|
||||
}
|
||||
}`;
|
||||
|
||||
exports.trigger = (req, res) => {
|
||||
const GMAPS_API_KEY = process.env.GMAPS_API_KEY;
|
||||
const HASURA_GRAPHQL_ENGINE_URL = process.env.HASURA_GRAPHQL_ENGINE_URL;
|
||||
|
||||
const { event: {op, data}, table } = req.body;
|
||||
|
||||
if (op === 'INSERT' && table.name === 'profile' && table.schema === 'public') {
|
||||
const { id, address } = data.new;
|
||||
fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${GMAPS_API_KEY}`).then( gmaps => {
|
||||
gmaps.json().then( gmapsResponse => {
|
||||
if (gmapsResponse.results && gmapsResponse.results.length === 0) {
|
||||
res.json({error: true, data: gmapsResponse, message: `no results for address ${address}`});
|
||||
return;
|
||||
}
|
||||
const { lat, lng } = gmapsResponse.results[0].geometry.location;
|
||||
query({
|
||||
query: MUTATION_UPDATE_LAT_LONG,
|
||||
endpoint: HASURA_GRAPHQL_ENGINE_URL,
|
||||
variables: { id, lat, lng },
|
||||
}).then( hgeResponse => {
|
||||
res.json({error: false, data: hgeResponse.data});
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
res.json({error: false, message: 'ignored event'});
|
||||
}
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "cloudfunction",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"graphqurl": "^0.3.1",
|
||||
"node-fetch": "^2.2.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
# This file specifies files that are *not* uploaded to Google Cloud Platform
|
||||
# using gcloud. It follows the same syntax as .gitignore, with the addition of
|
||||
# "#!include" directives (which insert the entries of the given .gitignore-style
|
||||
# file at that point).
|
||||
#
|
||||
# For more information, run:
|
||||
# $ gcloud topic gcloudignore
|
||||
#
|
||||
.gcloudignore
|
||||
# If you would like to upload your .git directory, .gitignore file or files
|
||||
# from your .gitignore file, remove the corresponding line
|
||||
# below:
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
.env.yaml
|
||||
.prod.env.yaml
|
||||
|
1
community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/.gitignore
vendored
Normal file
1
community/boilerplates/serverless-triggers/google-cloud-functions/python/echo/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.prod.env.yaml
|
@ -0,0 +1,41 @@
|
||||
# Setup table
|
||||
|
||||
Create the table using the console:
|
||||
|
||||
```
|
||||
Table name: profile
|
||||
|
||||
Columns:
|
||||
|
||||
id: Integer auto-increment
|
||||
name: Text
|
||||
address: Text
|
||||
lat: Numeric, Nullable
|
||||
lng: Numeric, Nullable
|
||||
```
|
||||
|
||||
# Deploy Google Cloud function
|
||||
|
||||
Deploy the function:
|
||||
|
||||
```bash
|
||||
gcloud beta functions deploy python-echo \
|
||||
--runtime python37 \
|
||||
--trigger-http
|
||||
```
|
||||
|
||||
Get the trigger URL:
|
||||
```yaml
|
||||
httpsTrigger:
|
||||
url: https://us-central1-hasura-test.cloudfunctions.net/python-echo
|
||||
```
|
||||
|
||||
Open Hasura console, goto `Events -> Add Trigger` and create a new trigger:
|
||||
```
|
||||
Trigger name: profile_change
|
||||
Schema/Table: public/profile
|
||||
Operations: Insert, Update, Delete
|
||||
Webhook URL: [Trigger URL]
|
||||
```
|
||||
|
||||
Once the trigger is created, goto `Data -> profile -> Insert row` and add a row.
|
@ -0,0 +1,11 @@
|
||||
from flask import jsonify
|
||||
|
||||
def function(request):
|
||||
request_json = request.get_json()
|
||||
op = request_json['event']['op']
|
||||
data = request_json['event']['data']
|
||||
name = request_json['table']['name']
|
||||
schema = request_json['table']['schema']
|
||||
response = {'message': 'received event', 'data': {op, data, name, schema}}
|
||||
print(response)
|
||||
return jsonify(message='received event', data={'op': op, 'data': data, 'name': name, 'schema': schema})
|
Loading…
Reference in New Issue
Block a user