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
- 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
-
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
-
https://bbgithub.dev.bloomberg.com/kmamykin/graphql-bas-gw
- KYC has explored using GraphQL
- BNEF is currently investigating using GraphQL
- ... and maybe more!
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