Skip to content

Commit

Permalink
Merge pull request #1 from xolvio/bill-history-example
Browse files Browse the repository at this point in the history
Bill history example
  • Loading branch information
mmazur122 authored May 17, 2024
2 parents 7a03caf + 33edcd0 commit 8dad374
Show file tree
Hide file tree
Showing 17 changed files with 485 additions and 7 deletions.
6 changes: 5 additions & 1 deletion .scripts/subgraphs/docker-compose-networking.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#!/bin/bash

subgraphs=("inventory" "products" "users" "reviews")
subgraphs=("inventory" "products" "users" "reviews" "accounts" "bill_history")

url_inventory="http://inventory:4000/graphql"
url_products="http://products:4000/graphql"
url_users="http://users:4000/graphql"
url_reviews="http://reviews:4000/graphql"
url_accounts="http://accounts:4000/graphql"
url_bill_history="http://bill-history:4000/graphql"

schema_inventory="subgraphs/inventory/app/src/main/resources/graphql/inventory.graphqls"
schema_products="subgraphs/products/products.graphql"
schema_users="subgraphs/users/users.graphql"
schema_reviews="subgraphs/reviews/reviews.graphql"
schema_accounts="subgraphs/accounts/accounts.graphql"
schema_bill_history="subgraphs/bill-history/bill-history.graphql"
6 changes: 5 additions & 1 deletion .scripts/subgraphs/localhost-networking.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#!/bin/bash

subgraphs=("products" "inventory" "users" "reviews")
subgraphs=("products" "inventory" "users" "reviews" "accounts" "bill_history")

url_products="http://localhost:4001/graphql"
url_inventory="http://localhost:4002/graphql"
url_users="http://localhost:4003/graphql"
url_reviews="http://localhost:4004/graphql"
url_accounts="http://localhost:4005/graphql"
url_bill_history="http://localhost:4006/graphql"

schema_products="subgraphs/products/products.graphql"
schema_inventory="subgraphs/inventory/app/src/main/resources/graphql/inventory.graphqls"
schema_users="subgraphs/users/users.graphql"
schema_reviews="subgraphs/reviews/reviews.graphql"
schema_accounts="subgraphs/accounts/accounts.graphql"
schema_bill_history="subgraphs/bill-history/bill-history.graphql"
10 changes: 10 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@ services:
build: subgraphs/reviews
ports:
- "4004:4000"
accounts:
container_name: accounts
build: subgraphs/accounts
ports:
- "4005:4000"
bill-history:
container_name: bill-history
build: subgraphs/bill-history
ports:
- "4006:4000"
12 changes: 12 additions & 0 deletions subgraphs/accounts/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:18-bookworm-slim

WORKDIR /usr/src/app

COPY package.json .

RUN npm install

COPY accounts.js .
COPY accounts.graphql .

CMD [ "node", "accounts.js" ]
31 changes: 31 additions & 0 deletions subgraphs/accounts/accounts.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.1",
import: ["@key", "@shareable", "@tag", "@inaccessible", "@composeDirective", "@requires", "@external"])

type Query {
accounts: [Account]
account(billingAccountNumber: String!): Account
}

type Account {
id: ID!
billingAccountNumber: String!
name: String
email: String
settings: AccountSettings
amountDue: Float
balance: Float
}

type AccountSettings @shareable {
paperless: Boolean
}

interface BillDetail {
billingAccountNumber: String!
}

type CurrentBillDetail implements BillDetail @key(fields: "billingAccountNumber") {
billingAccountNumber: String!
account: Account
}
92 changes: 92 additions & 0 deletions subgraphs/accounts/accounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Open Telemetry (optional)
const {ApolloOpenTelemetry} = require('supergraph-demo-opentelemetry');

if (process.env.APOLLO_OTEL_EXPORTER_TYPE) {
new ApolloOpenTelemetry({
type: 'subgraph',
name: 'accounts',
exporter: {
type: process.env.APOLLO_OTEL_EXPORTER_TYPE, // console, zipkin, collector
host: process.env.APOLLO_OTEL_EXPORTER_HOST,
port: process.env.APOLLO_OTEL_EXPORTER_PORT,
}
}).setupInstrumentation();
}

const {ApolloServer, gql} = require('apollo-server');
const {buildSubgraphSchema, printSubgraphSchema} = require('@apollo/subgraph');
const {readFileSync} = require('fs');
const {printSchema} = require('graphql');

const port = process.env.APOLLO_PORT || 4000;

// Data sources
const accounts = [
{
id: '1',
billingAccountNumber: '123',
name: 'Alice',
email: '[email protected]',
amountDue: 100.0,
balance: 100.0,
settings: {paperless: true}
},
{
id: '2',
billingAccountNumber: '456',
name: 'Bob',
email: '[email protected]',
amountDue: 200.0,
balance: 50.0,
settings: {paperless: false}
},
{
id: '3',
billingAccountNumber: '789',
name: 'Charlie',
email: '[email protected]',
amountDue: 300.0,
balance: 500.0,
settings: {paperless: true}
},
];

// GraphQL
const typeDefs = gql(readFileSync('./accounts.graphql', {encoding: 'utf-8'}));
const resolvers = {
Query: {
accounts: (_, args, context) => {
return accounts;
},
account: (_, args, context) => {
return accounts.find(account => account.billingAccountNumber === args.billingAccountNumber);
}
},
CurrentBillDetail: {
__resolveReference: (reference) => {
return {
...reference,
...accounts.find(account => account.billingAccountNumber === reference.billingAccountNumber)
};
},
account: (account) => {
return accounts.find(acc => acc.billingAccountNumber === account.billingAccountNumber);
}
},
Account: {
account: (account) => {
return account[0];
},
__resolveReference: reference => {
return accounts.find(account => account.billingAccountNumber === reference.billingAccountNumber)
}
}
}
const schema = buildSubgraphSchema({typeDefs, resolvers});

const server = new ApolloServer({schema: schema});
server.listen({port: port}).then(({url}) => {
console.log(`🚀 Accounts subgraph ready at ${url}`);
}).catch(err => {
console.error(err)
});
18 changes: 18 additions & 0 deletions subgraphs/accounts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "subgraph-accounts",
"version": "1.1.18",
"description": "",
"main": "accounts.js",
"scripts": {
"start": "node accounts.js"
},
"dependencies": {
"@apollo/subgraph": "2.7.4",
"apollo-server": "3.13.0",
"supergraph-demo-opentelemetry": "0.2.4",
"graphql": "16.8.1"
},
"keywords": [],
"author": "",
"license": "MIT"
}
12 changes: 12 additions & 0 deletions subgraphs/bill-history/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:18-bookworm-slim

WORKDIR /usr/src/app

COPY package.json .

RUN npm install

COPY bill-history.js .
COPY bill-history.graphql .

CMD [ "node", "bill-history.js" ]
44 changes: 44 additions & 0 deletions subgraphs/bill-history/bill-history.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.1",
import: ["@key", "@shareable", "@tag", "@inaccessible", "@composeDirective", "@requires", "@external"])

type Query {
bills: [BillDetailResponse]
}

interface BillDetail {
id: ID!
billingAccountNumber: String!
isCurrent: Boolean!
hints: [BillDetailHint]
}

type CurrentBillDetail implements BillDetail @key(fields: "billingAccountNumber") {
id: ID!
billingAccountNumber: String!
isCurrent: Boolean!
account: Account @external
hints: [BillDetailHint] @requires(fields: "account { settings { paperless } }")
}

type PastBillDetail implements BillDetail {
id: ID!
isCurrent: Boolean!
billingAccountNumber: String!
hints: [BillDetailHint]
}

union BillDetailResponse = CurrentBillDetail | PastBillDetail

type BillDetailHint {
id: ID!
body: String
}

type Account {
settings: AccountSettings @external
}

type AccountSettings @shareable {
paperless: Boolean
}
71 changes: 71 additions & 0 deletions subgraphs/bill-history/bill-history.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const { ApolloServer, gql } = require('apollo-server');
const { buildSubgraphSchema, printSubgraphSchema } = require('@apollo/subgraph');
const { readFileSync } = require('fs');
const { printSchema } = require('graphql');

const port = process.env.APOLLO_PORT || 4000;

// Data sources
const staticHints = [
{ id: '1', body: 'static hint 1' },
{ id: '2', body: 'static hint 2' },
{ id: '3', body: 'static hint 3' },
];

const billHistory = [
{ id: '1', billingAccountNumber: '123', accountId: '1', isCurrent: true, hints: [] },
{ id: '2', billingAccountNumber: '123', isCurrent: false, account: { paperless: true }, hints: staticHints },
{ id: '3', billingAccountNumber: '123', isCurrent: false, account: { paperless: false }, hints: staticHints },
{ id: '4', billingAccountNumber: '456', isCurrent: false, account: { paperless: true }, hints: staticHints },
{ id: '5', billingAccountNumber: '789', isCurrent: false, account: { paperless: false }, hints: staticHints },
];

// GraphQL
const typeDefs = gql(readFileSync('./bill-history.graphql', { encoding: 'utf-8' }));
const resolvers = {
Query: {
bills: async (_, args, context) => {
return billHistory;
},
},
BillDetailResponse: {
__resolveType(obj) {
if (obj.isCurrent) {
return 'CurrentBillDetail';
} else {
return 'PastBillDetail';
}
}
},
CurrentBillDetail: {
hints: (obj, args, context) => {
if (obj.account?.settings?.paperless) {
return [
staticHints[0],
staticHints[2],
]
}
return null;
},
__resolveReference: (reference) => {
let result = {};
if (reference.billingAccountNumber) {
result = billHistory.find(bh => bh.billingAccountNumber === reference.billingAccountNumber);
} else return { id: 'rover', package: '@apollo/rover', ...reference };

return {
...reference,
...result,
};
},
},
};

const schema = buildSubgraphSchema({ typeDefs, resolvers });

const server = new ApolloServer({ schema });
server.listen({ port }).then(({ url }) => {
console.log(`🚀 Bill History subgraph ready at ${url}`);
}).catch(err => {
console.error(err);
});
18 changes: 18 additions & 0 deletions subgraphs/bill-history/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "subgraph-bill-history",
"version": "1.1.18",
"description": "",
"main": "bill-history.js",
"scripts": {
"start": "node bill-history.js"
},
"dependencies": {
"@apollo/subgraph": "2.7.4",
"apollo-server": "3.13.0",
"supergraph-demo-opentelemetry": "0.2.4",
"graphql": "16.8.1"
},
"keywords": [],
"author": "",
"license": "MIT"
}
4 changes: 2 additions & 2 deletions subgraphs/products/products.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ type Product implements ProductItf & SkuItf @key(fields: "id") @key(fields: "sku
package: String
variation: ProductVariation
dimensions: ProductDimension
createdBy: User @external
createdBy: User
hidden: String
reviewsScore: Float!
oldField: String
reviewsCount: Int! @external
discount: Float @requires(fields: "reviewsCount createdBy { email }")
discount: Float @requires(fields: "reviewsCount")
}
enum ShippingClass {
STANDARD
Expand Down
6 changes: 3 additions & 3 deletions subgraphs/reviews/reviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ const resolvers = {
}
},
Product: {
reviews: (product) => reviews.filter(r => r.product_id === product.id),
reviews: (product) => {
return reviews.filter(r => r.product_id === product.id);
},
reviewsCount: (product) => {
console.log("product: ", product);
console.log("product reviewsCount: ", reviews.filter(r => r.product_id === product.id).length, product);
return reviews.filter(r => r.product_id === product.id).length;
},
reviewsScore: (product) => 4.6, // Static example score
Expand Down
Loading

0 comments on commit 8dad374

Please sign in to comment.