Wardenclyffe: GraphQL for Bloomberg Consumer Web

  • A brief background of the Web Shared Services (WSS) infrastructure with regard to content consumption
  • What is GraphQL
  • How does GraphQL look for Bloomberg.com (Wardenclyffe)
    • Live Demo
       
  • State of future enhancements
  • Q & A

Bloomberg.com


Infrastructure Background

Daper (Web Shared Services)

Business

Politics

Markets

View

Gadfly

Daper (Web Shared Services)


Infrastructure Background

Business

Politics

Markets

View

Gadfly

Daper (Web Shared Services)

Bbiz
SA

Pol
SA

Mar
SA

Gadfly
SA


Infrastructure Background

Bloomberg.com Web

Daper (Web Shared Services)

Bbiz
SA

Pol
SA

Mar
SA

Gadfly
SA

Bloomberg.com Web

Bloomberg Mobile Apps


Infrastructure Background

Daper (Web Shared Services)

Universal Service Adapter (Wardenclyffe)

Bloomberg.com Web

Bloomberg Mobile Apps

Articles

Market
Data

Curated Pages


Infrastructure Background

Bloomberg.com Web

A Brief Introduction to GraphQL

  • Strictly typed schema for data:
type Article {
  id: String
  headline: String
  summary: String
  authors: [Person]
}
{
  article(id: "P3C1C16JTSEA01") {
    headline
    summary
  }
}
{
  "data": {
    "article": {
      "headline": "Elon Musk is Selling Flamethrowers",
      "summary": "The bizarre side venture has already
                  generated $5 million for his tunnel business."
    }
  }
}


Introduction to GraphQL

  • Request schema subset of data's schema:
     
  • Response matches request format:
  • This allows a single REST endpoint to handle all requests to the API, as the consumer sends the schema alongside their request, ensuring the information sent is exactly what they want, without extraneous information


Introduction to GraphQL

GraphQL at Bloomberg

  • Web Shared Services - Wardenclyffe
    • Decided on by the team that had worked on Daper previously, after evaluating other options such as HATEOS and JSON-LD
       
  • Live example
     
  • Several other teams have considered a GraphQL API, and may already be using using one!


GraphQL at Bloomberg

Wardenclyffe

Store

Schema

Model


GraphQL at Bloomberg

Schema

import { GraphQLString, GraphQLNonNull } from 'graphql';
import SecurityCategory from './model';

export default {
  type: SecurityCategory,

  args: {
    id: { type: new GraphQLNonNull(GraphQLString) },
  },

  resolve: async (_, { id }, Store) => {
    const category = await Store.Securities.findCategoryById(id);

    return { ...category, id };
  },
};
  • Responsible for Defining what arguments the data can accept and how that information is found and returned to the requester


GraphQL at Bloomberg

Model

import { GraphQLObjectType, GraphQLString } from 'graphql';

export default new GraphQLObjectType({
  name: 'SecurityCategory',

  fields: () => ({
    id: { type: GraphQLString },
    type: { type: GraphQLString },
    terminalSecurityType: { type: GraphQLString },
    mediaSecurityType: { type: GraphQLString },
    mediaSecuritySubtype: { type: GraphQLString },
  }),
});
  • Defines the types of each attribute that is accessible on the type. If the attribute is not a basic type, then it also specifies how to resolve that value.


GraphQL at Bloomberg

Store

import securityCategories from './data/security/categories.json';
import { translateFields, getCalcrts } from './data/security/helper';

const securityCategoryFields = Object.keys(securityCategories)
                                    .map(key => securityCategories[key])
                                    .join(',');

async function getSecurityCategory(daper, id) {
  const params = { securities: id, fields: securityCategoryFields };

  const resource = await daper.resource(['finance', 'reference'], { params });
  const { data } = resource.toJSON();

  return translateFields(data[id], securityCategories);
}

export default function createStore(daperClient) {
  return {
    findCategoryById: (id) => getSecurityCategory(daperClient, id)
  };
}
  • Responsible for defining the connections to the underlying data sources (in this case WSS Daper) and general transforms on that data


GraphQL at Bloomberg

Live Demo


GraphQL at Bloomberg

Other Teams

Areas for Improvement


Future Improvements

Schema Introspection

Right now for many calls, regardless of how few fields are in the request schema, all fields are requested from upstream

If we instead only request fields being requested, this shrinks our request sizes substantially


Future Improvements

Caching Support

In lieu of the previous idea (or maybe in addition to if done carefully), we could also cache at the Wardenclyffe-tier for common shared calls.

Right now Wardenclyffe expects the consuming application to cache all data themselves, and provides no support.


Future Improvements

Better Joint Ownership

  • No shared permissions on the boxes
  • Defining Responsibilities:
    • Producers - What is the best way to access my information being provided?
    • Consumers - What is the best way to name my interfaces that are globally recognizable and consistent

Questions ?

Wardenclyffe

By Spencer Carver

Wardenclyffe

  • 183