Giter VIP home page Giter VIP logo

nestjs-graphql-azure-functions's Introduction

Nest Logo

Deploying Serverless NestJS GraphQL API to Azure Functions

Getting nest/azure-func-http and nest/graphql to play well together is tricky. There are several GH issues and SO posts on this topic with little in the way of a solution. Additionally, none of the official nest.js docs or samples contain a configuration with both graphql and azure functions.

The one source of reliable information on this topic is a blog post by trilon.io here. This is a good tutorial on creating a Nest.js REST api with nest/azure-func-http. However the tutorial steps to not carry over directly when creating a GraphQl API.

This repo and tutorial is a minimal example of a working integration of nest/azure-func-http and nest/graphql. I hope this helps some folks out!

Starting Point

I started this repo with the boilerplate from 23-type-graphql. This is a working repo with Typescript, GraphQL, and Nest but NOT nest/azure-func-http

Adding azure-func-http

$ nest add @nestjs/azure-func-http

This will install the function app boilerplate in the repo. Here is where this tutorial deviates from the trilion.io tutorial. Several of the default azure function configurations need to be altered along with some of your nest app code.

Steps

1. Change build script in package.json

- "build": "nest build"
+ "build": "rimraf dist && tsc -p tsconfig.build.json"

2. Remove the include from your tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "allowSyntheticDefaultImports": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true
  },
-  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

These two steps create seperate /src and /main directories in /dist.

  • /src is for your source code
  • /main is the entry point for the function app

3. Adjust Nest.js App

At this point the azure function will run but it will not resolve your GraphQL requests! Some changes need to be made to the nest app itself.

main.ts

import { ValidationPipe } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
+ app.enableCors();
+ app.setGlobalPrefix("api");
  await app.listen(3000);
}
bootstrap();

app.module.ts

import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { RecipesModule } from "./recipes/recipes.module";

@Module({
  imports: [
    RecipesModule,
    GraphQLModule.forRoot({
      installSubscriptionHandlers: true,
+     context: ({ req }) => ({ req }),
      autoSchemaFile: "schema.gql",
+     useGlobalPrefix: true
    })
  ]
})
export class AppModule {}
  1. Adjust function app config

host.json

{
  "version": "2.0",
+ "extensions": {
+   "http": {
+     "routePrefix": "api"
+   }
  }
}

index.ts

import { Context, HttpRequest } from "@azure/functions";
import { AzureHttpAdapter } from "@nestjs/azure-func-http";
import { createApp } from "../src/main.azure";

export default function(context: Context, req: HttpRequest): void {
+ context.res = {
+   headers: {
+     "Content-Type": "application/json"
+   }
+ };
  AzureHttpAdapter.handle(createApp, context, req);
}

Your GraphQL function app is good to go!!

$ npm run build && func host start

Testing out the app

Add a sample body to the create method in recipies.service.ts for testing.

recipies.service.ts

  async create(data: NewRecipeInput): Promise<Recipe> {
+    return {
+      id: "sample",
+      title: data.title,
+      description: data.description,
+      creationDate: new Date(),
+      ingredients: data.ingredients
+    } as Recipe;
- return {} as any;
  }

fire up http://localhost:7071/api/graphql and run a mutation

mutation($newRecipeData: NewRecipeInput!) {
  addRecipe(newRecipeData: $newRecipeData) {
    creationDate
  }
}

query variables

{
  "newRecipeData": {
    "title": "Salad",
    "description": "Im trying to be healthy and im disappointed in my self",
    "ingredients": ["leaves", "sadness"]
  }
}

you should get back something like....

{
  "data": {
    "addRecipe": {
      "creationDate": 1582340836192
    }
  }
}

Deploying to Azure Functions

The battle has been won but the war has just begun

Getting the function to run remotely on azure is not clear cut. I have found that the best configuration options are Function app V3 and WEBSITES_NODE_DEFAULT_VERSION set to ~12

Documentation on how to changes these Azure related setting can be found here

If you are using vscode there is some helpful extensions for deploying function apps. Your can read about that here

To build and run from the command line use:

$ npm run build && func azure functionapp publish <APP_NAME>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.