ApolloServer, AzureFunctions and local debugging

I wanted to jog down some notes that’ll help with local debugging of Apollo Server with Azure Functions.

Firstly, due to changes to Azure API routing - specifically x-ms-privatelink-id having strange invalid characters - we need to expand the function handler and blank out the x-ms-privatelink-id property.

https://github.com/Azure/azure-functions-host/issues/6013

Now to get local debug happening - we must configure CORS.

Add the cors settings - origin can be ‘true’ for every url, or ‘http://localhost:4200’ if only for your local build.

Additionally, copy the access-control-request-headers to Access-Control-Request-Headers because ApolloServer applyMiddleWare is case sensitive.

https://github.com/apollographql/apollo-server/issues/4178

const graphqlHandler = server.createHandler({
    cors:{
        origin: true,
        credentials: true,
    }
});
export default (context: Context, req: HttpRequest) => {
    // https://github.com/Azure/azure-functions-host/issues/6013
    req.headers['x-ms-privatelink-id'] = '';
    // apollo-server only reads this specific string
    req.headers['Access-Control-Request-Headers'] = req.headers['Access-Control-Request-Headers'] || req.headers['access-control-request-headers'];
    return graphqlHandler(context, req);
}

These changes by itself isn’t enough, we also need to make sure the Azure Functions runtime is forwarding the options method correctly to our Apollo Server. Make sure ‘methods’ contains ‘options’ otherwise the Azure Functions local runtime will not accept the browser pre-flight request.

(this second one was the one that got me for a while - why wasn’t Apollo Server options being called?!)

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post",
        "options"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ],
  "scriptFile": "../dist/graphql/index.js"
}

Simple custom Angular (Angular2) Pipe that extends Number

We have a lot of code that looks like this in our new Angular (Angular2) module:

<div style="width:210px">
    <div>
        {{ (overviewDetails.TotalTurnoverActualSecured ?
      (overviewDetails.TotalTurnoverActualSecured / 1000000) : 0) | number:'1.2-2' }}
    </div>
    <div>{{ overviewDetails.TotalTurnoverActualSP / 1000000 
      | number:'1.2-2' }}</div>
    <div>{{ overviewDetails.TotalTurnoverActualSPF / 1000000 
      | number:'1.2-2' }}</div>
    <div style="clear:both"></div>
</div>

The main reason is that we just want to display numbers in 1.2 million, not 1200,000.

So obviously, we think about wrapping this in a custom Pipe function.

number is a Pipe name for the DecimalPipe class.  So we can extend that and borrow all the work the DecimalPipe does with parsing and formatting.

import { Pipe } from '@angular/core';
import { DecimalPipe } from '@angular/common';

@Pipe({
  name: 'million'
})
export class MillionPipe extends DecimalPipe {
  transform(value: number): any {
    return super.transform(((value || 0)/ 1000000), "1.2-2");  
  }
}

The Angular2 template then simplifies down to:

<div style="width:210px">
    <div>{{ overviewDetails.TotalTurnoverActualSecured | million }}</div>
    <div>{{ overviewDetails.TotalTurnoverActualSP  | million }}</div>
    <div>{{ overviewDetails.TotalTurnoverActualSPF  | million }}</div>
    <div style="clear:both"></div>
</div>

It is so nice to work with a Proper Object-Oriented language like TypeScript here.  Look at that extends.  <3