Awesome
Welcome To The Universal GraphQL Server Template ·
Clone this project to create your own GraphQL server in less than 1 minute and deploy it on any serverless platform..
Targeted serverless platforms:
- Locally (using express under the hood)
- Zeit Now (using express under the hood)
- Google Cloud Functions (incl. Firebase Function)
- AWS Lambdas (COMING SOON...)
- Azure Functions (COMING SOON...)
In any of those scenarios above, the code is still the exact same, hence the use of the term universal.
Copy/paste the following in your terminal if you want to run your first GraphQL api (http://localhost:4000) including a GraphiQL interface (http://localhost:4000/graphiql) on your local machine in less than 30 seconds:
git clone https://github.com/nicolasdao/graphql-universal-server.git your-project
cd your-project
npm install
npm start
This will serve 2 endpoints:
- http://localhost:4000: This is the GraphQL endpoint that your client can start querying.
- http://localhost:4000/graphiql: This is the GraphiQL Web UI that you can use to test and query your GraphQL server.
Deploying that api to Zeit Now will take between 15 seconds to 1.5 minute (depending on whether you need to login/creating a free Zeit account or not).
If you haven't installed Zeit now-CLI yet or you need to login/create an account, then copy/paste this in your terminal:
npm install now -g
now login
npm run deploy:prod
The above will work the exact same way whether you have an account or not. This is free, so don't worry about it.
If you're already logged in, then simply run this:
npm run deploy:prod
This server will serve both a GraphQL endpoint as well as a GraphiQL Web UI.
This has been made possible thanks to the following awesome projects:
- webfunc: A serverless framework that makes it possible to run any express middleware on FaaS.
- Zeit Now: A deployment tool CLI & a serveless infrastructure.
- now-flow: A wrapper around now-CLI that makes it super simple to configure and deploy to multiple environments.
How To Use It
Local Deployment
npm start
This command will start an express server and will automatically reload your code thanks to node-dev. 2 endpoints will be immediately available:
- http://localhost:4000: This is the GraphQL endpoint that your client can start querying.
- http://localhost:4000/graphiql: This is the GraphiQL Web UI that you can use to test and query your GraphQL server.
Serverless Deployment
Prerequisite
All deployments to serverless are managed by the awesome Zeit now-CLI. That means that tool must be installed globally on your local machine. Simply run:
npm install -g now
Deploying To Now
More details about choosing now over a FaaS in the Annex below.
To deploy on now, first make sure you're logged in (if you don't have an account, it will create one for free. The free version is more than enough to get familiar with now):
now login
Whether you're a new user with no account or not, the above command will work the exact same way.
Then deploying to Zeit Now is as simple as running:
npm run deploy:prod
WHAT THIS DOES BEYOND DEPLOYING TO ZEIT NOW In a nutshell, the npm script will use the Zeit now-CLI to deploy your first GraphQL api to Zeit Now. Normally, you would have to make sure that you have a start script in your package.json. If you wanted to alias your deployment, you would have to run another command (
now alias ...
) after your deployment is successful. Because all those steps can become a bit messy and error prone when you manage mutliple environments (prod, staging, ...), we're using a really usefull wrapper around now-CLI called now-flow. If you want to know more about the different steps behind now-flow, jump to the annex A.2. What does "nowflow production" do?.
Deploying To Google Cloud Functions
To deploy to Google Cloud Function, first make sure you're logged in:
now gcp login
You will have to select a GCP project.
IMPORTANT: Make sure you've enabled billing for that project, otherwise the deployment will fail miserably.
Then this is as simple as running:
npm run deploy:staging
WHAT THIS DOES BEYOND DEPLOYING TO GOOGLE CLOUD FUNCTION Same as for the deployement to now, except that aliasing is not supported.
now.json Config File Explained
The now.json file is used by Zeit now-CLI to manage deployment's configuration. Because of its usefulness, the team behind webfunc decided to use the same file to store more information relevant to environments.
{
"headers": {
"Access-Control-Allow-Methods": "GET, HEAD, OPTIONS, POST",
"Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept"
},
"environment": {
"active": "default",
"default": {
"hostingType": "localhost"
},
"staging": {
"hostingType": "gcp",
"gcp": {
"functionName": "your-webfunc-app",
"memory": 128
}
},
"production": {
"hostingType": "now",
"scripts": {
"start": "NODE_ENV=production node index.js"
},
"alias": "your-webfunc-app"
}
}
}
- "headers": Control the CORS setup provided out-of-the-box by webfunc.
- "environment": This property stores variables specific to environments. The "active" property is the only exception. That property defines which environment is currently active. When the command
npm run deploy:prod
is run, the underlying executed script isnowflow production
. That command will automatically set the "active" property to "production" in the now.json (more details about the entire series of tasks being run in the annex A.2. What does "nowflow production" do?).
Notice the difference between the "production" configuration and the "staging" one. In the production configuration, a "scripts" and a "alias" property are setup. This will respectively ensure that the package.json's "start" script is properly setup and that once the deployment to Zeit Now is completed, the right alias is associated to it. In the staging configuration, there is no need for a start script or an alias as they are both irrelevant as far as Google Cloud Function is concerned. On the other hand, a "gcp" property is required to configure the function's name as well as the memory size of the allocated to the function.
Annex
A.1. Why Using Now Over FaaS
Zeit Now is a serverless infrastructure (i.e. you don't have to worry about the servers that host your app. They are fully managed by a third party who also takes care of load balancing, domain name, SSL certs, scaling up/down), whereas AWS Lambda or Google Cloud Function are better described as FaaS (i.e. Function as a Service). In both case, you just need to focus on one thing only: Writing code.
Depending on what you're trying to achieve, Zeit Now could be a better alternative than a FaaS for the following reasons:
- No cold start (if you've made sure that there is at least 1 server up at any time)
- Express server with all the bells and whistle. That means more features (e.g. websocket, managing states, not screwing your RDBMS connection pools, ...)
It offers a free tier with 3 instances, so you can develop at your ease. Each deployment receives a unique URL that stays there forever (unless you explicitly delete it). You can deploy infinitely. Without entering into too many details, each time you deploy, the previous deployment will scale down to 0 instances. That's what allows you to deploy infinitely on the free tier without exceeding the free quota of 3 instances.
You can read more about Zeit Now here.
A.2. What does "nowflow production" do?
The above is a shortcut for nowflow production
. now-flow is a wrapper around now-CLI that makes it super simple to configure and deploy to multiple environments. Under the hood, this happens:
-
Confirm that there is a valid now.json file located in the root folder.
-
Confirm that there is a production property under the environment property of the now.json. Example:
{ "environment": { "production": { "hostingType": "now", "scripts": { "start": "NODE_ENV=production node index.js" }, "alias": "your-webfunc-app" } } }
-
Update both the package.json and the now.json so they fit the configuration defined for the specific environment.
- Create backups for the package.json and the now.json respectively called .package.backup.json and .now.backup.json in case something goes wrong (those files will be deleted if all goes well).
- If the configuration for the specific environment in the now.json describes a "scripts" property, then update the package.json's "scripts" property accordingly.
- If the configuration for the specific environment in the now.json describes an "alias" property, then update the now.json's "alias" property accordingly.
- If the configuration for the specific environment in the now.json describes a "gcp" property (Google Cloud Platform, i.e. Google Function), then update the now.json's "gcp" property accordingly.
- Deploy to the platform described in the "hostingType" property of the specific environment of the now.json.
- If an "alias" has been defined, and if the "hostingType" is "now", then alias the deployment.
- If everything went well, then restore both the package.json and the now.json to their original state, and delete their respective backups (i.e. .package.backup.json and .now.backup.json).
License
Copyright (c) 2018, Neap Pty Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Neap Pty Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NEAP PTY LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<p align="center"><a href="https://neap.co" target="_blank"><img src="https://neap.co/img/neap_color_horizontal.png" alt="Neap Pty Ltd logo" title="Neap" height="89" width="200"/></a></p>