Using Klotho with GraphQL Yoga and Express
Overview
This tutorial shows how to leverage Klotho's existing support for Express to create a cloud-ready GraphQL application using GraphQL Yoga.
Getting Started
Prerequisites
Repository
Clone our sample apps git repo and install the npm packages for the ts-graphql-yoga
app.
git clone https://github.com/klothoplatform/sample-apps.git
cd sample-apps/ts-graphql-yoga
npm install
Application Overview
The GraphQL Yoga sample application is an Express app that exposes a GraphQL Yoga server on its /graphql
route. The server's schema includes a single query, hello
, that returns "Hello from Klotho!" when executed.
This application utilizes the following annotations:
Wiring the Application for Compilation with Klotho
To wire the GraphQL Yoga application for compilation with Klotho, first a GraphQL Yoga server, graphQLServer
, is created.
import { createServer } from "@graphql-yoga/node";
const graphQLServer = createServer({
schema: {
... // the schema is included in the complete sample application
},
});
...
Then an Express app is created and graphQLServer
is mounted as a route handler on its /graphql
route.
...
import * as express from "express";
const app = express();
app.use('/graphql', graphQLServer)
Finally, the application listens for requests to the Express app with an invocation of
app.listen
annotated with @kotho::expose
.
/* @klotho::expose {
* target = "public"
* id = "graphql-yoga-gateway"
* }
*/
app.listen(3000, async () => {
console.log(
'Running GraphQL Yoga API Server at http://localhost:3000/graphql'
);
});
Compiling the Application with Klotho
Start by compiling the typescript application into javascript.
npx tsc
The compiled output will be located in the ./dist
directory.
Then compile the application with Klotho.
klotho . --app ts-graphql-yoga --provider aws
██╗ ██╗██╗ ██████╗ ████████╗██╗ ██╗ ██████╗
██║ ██╔╝██║ ██╔═══██╗╚══██╔══╝██║ ██║██╔═══██╗
█████╔╝ ██║ ██║ ██║ ██║ ███████║██║ ██║
██╔═██╗ ██║ ██║ ██║ ██║ ██╔══██║██║ ██║
██║ ██╗███████╗╚██████╔╝ ██║ ██║ ██║╚██████╔╝
╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝
Adding resource input_file_dependencies:
Adding resource exec_unit:main
index.js: Adding in catchall route for prefix '/graphql' for middleware 'graphQLServer'
Found 2 route(s) for middleware 'graphQLServer'
Adding resource gateway:graphql-yoga-gateway
Adding resource topology:ts-graphql-yoga
Adding resource infra_as_code:Pulumi (AWS)
In the ./compiled
folder, you will find the Infrastructure-as-Code (IaC) for your cloud-native application ready for deployment.
You will also find a file called ts-graphql-yoga.png
, visualizing the topology output of your compiled application:
The topology diagram shows that Klotho has generated IaC targeting AWS to deploy an API Gateway that invokes a Lambda function serving the application.
Deploying the application
Once the IaC has been generated, you can deploy the cloud-native version of the application with Pulumi.
First, use the Pulumi CLI to set the region aws:region
setting for the application's Pulumi stack.
This is the AWS region that Pulumi will deploy the application to.
pulumi config set aws:region <region> --cwd './compiled' --stack ts-graphql-yoga
Press ENTER
(⏎
) to confirm that you want to create the ts-graphql-yoga
Pulumi stack.
If you would like to create this stack now, please press <ENTER>, otherwise press ^C:
Created stack 'ts-graphql-yoga'
Next, change the current working directory to ./compiled
and install the dependencies of the Pulumi application generated by Klotho.
cd compiled
npm install
Then deploy the application by running pulumi up
.
pulumi up
Pulumi will display a preview of all the cloud resources it will create as part of the deployment.
Previewing update (ts-graphql-yoga)
Type Name Plan
+ pulumi:pulumi:Stack ts-graphql-yoga-ts-graphql-yoga create..
+ ├─ awsx:ecr:Repository ts-graphql-yoga create
+ │ └─ aws:ecr:LifecyclePolicy ts-graphql-yoga create
+ ├─ aws:ecr:Repository ts-graphql-yoga create
+ ├─ aws:apigateway:RestApi graphql-yoga-gateway create
+ │ ├─ aws:apigateway:Resource graphql-yoga-gatewaygraphql/ create
+ │ │ └─ aws:apigateway:Method ANY-graphql-e6862 create
+ │ │ └─ aws:apigateway:Integration lambda-ANY-graphql-e6862 create
+ │ ├─ aws:apigateway:Resource graphql-yoga-gatewaygraphql/{rest+}/ create
+ │ │ └─ aws:apigateway:Method ANY-rest-d5c2f create
+ pulumi:pulumi:Stack ts-graphql-yoga-ts-graphql-yoga create
+ │ └─ aws:apigateway:Deployment graphql-yoga-gateway-deployment create
+ │ └─ aws:apigateway:Stage graphql-yoga-gateway-stage create
+ ├─ aws:iam:Role ts-graphql-yoga_0d6e4_LambdaExec create
+ │ ├─ aws:iam:Policy ts-graphql-yoga-main-exec create
+ │ └─ aws:iam:RolePolicyAttachment ts-graphql-yoga-main-exec create
+ ├─ aws:cloudwatch:LogGroup main-function-api-lg create
+ ├─ aws:iam:RolePolicyAttachment ts-graphql-yoga-main-lambdabasic create
+ ├─ aws:s3:Bucket create
+ ├─ aws:lambda:Function main create
+ ├─ aws:lambda:Permission ANY-graphql-permission create
+ └─ aws:lambda:Permission ANY-graphqlrest-permission create
Outputs:
apiUrls : [
[0]: output<string>
]
deploymentPortal: "None - Opted out of topology upload by default"
Resources:
+ 22 to create
Do you want to perform this update? [Use arrows to move, enter to select, type to filter]
> yes
no
details
Select yes
from the displayed options to start the deployment process and then wait until Pulumi has completed the deploying the application's stack.
This usually takes 3 minutes.
When Pulumi has finished deploying, you will see the completion status and the AWS provided API Gateway URL for your API:
Outputs:
apiUrls : [
[0]: "https://<gateway_id>.execute-api.<region>.amazonaws.com/stage"
]
deploymentPortal: "None - Opted out of topology upload by default"
Resources:
+ 22 created
Duration: 2m31s
Testing the Deployed Application
To test the application one it has been deployed to the cloud, use your browser to navigate to the generated API Gateway's /graphql
route.
https://<gateway_id>.execute-api.<aws_region>.amazonaws.com/stage/graphql
This will load the GraphiQL, an in-browser GraphQL IDE which we can use to execute the hello
query.
Copy the hello
query to your GraphiQL window and try it out for yourself!
query {
hello
}
Cleanup
When you're done with the tutorial, you can destroy the created resources by running pulumi destroy
from the ./compiled
directory and selecting yes
when prompted.
pulumi destroy