{"id":1042,"date":"2020-04-12T10:48:27","date_gmt":"2020-04-12T09:48:27","guid":{"rendered":"https:\/\/www.muratyaman.co.uk\/wp\/?p=1042"},"modified":"2020-04-12T12:13:31","modified_gmt":"2020-04-12T11:13:31","slug":"graphql-services-using-node-and-apollo","status":"publish","type":"post","link":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/2020\/04\/graphql-services-using-node-and-apollo\/","title":{"rendered":"GraphQL Services using Node and Apollo"},"content":{"rendered":"<p>I have prepared 2 repos to implement FakeBank using <a href=\"https:\/\/graphql.org\/\">GraphQL<\/a>:<\/p>\n<p>1. JavaScript: <a href=\"https:\/\/github.com\/muratyaman\/fakebank-js\">https:\/\/github.com\/muratyaman\/fakebank-js<\/a><\/p>\n<p>2. TypeScript: <a href=\"https:\/\/github.com\/muratyaman\/fakebank-ts\">https:\/\/github.com\/muratyaman\/fakebank-ts<\/a><\/p>\n<p>Architecture can be like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-480x360.jpg\" alt=\"\" width=\"480\" height=\"360\" class=\"aligncenter size-medium wp-image-1043\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-480x360.jpg 480w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-768x576.jpg 768w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-887x665.jpg 887w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture.jpg 960w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p>FakeBank uses:<\/p>\n<p>* GraphQL<br \/>\n&#8211; <a href=\"https:\/\/graphql.org\/\">https:\/\/graphql.org\/<\/a><br \/>\n&#8211; &#8220;GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.&#8221;<\/p>\n<p>* GraphQL-JS<br \/>\n&#8211; <a href=\"https:\/\/github.com\/graphql\/graphql-js\">https:\/\/github.com\/graphql\/graphql-js<\/a><br \/>\n&#8211; &#8220;A reference implementation of GraphQL for JavaScript&#8221;<\/p>\n<p>* Apollo Server<br \/>\n&#8211; <a href=\"https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-server\">https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-server<\/a><br \/>\n&#8211; &#8220;Apollo Server is an open-source, spec-compliant GraphQL server that&#8217;s compatible with any GraphQL client&#8221;<\/p>\n<p>* Apollo Federation<br \/>\n&#8211; <a href=\"https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-federation\">https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-federation<\/a><br \/>\n&#8211; &#8220;&#8230; expose a single data graph that provides a unified interface for querying all of your backing data sources&#8221;<\/p>\n<p>* Apollo REST Data Source<br \/>\n&#8211; <a href=\"https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-datasource-rest\">https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-datasource-rest<\/a><br \/>\n&#8211; &#8220;This package exports a (RESTDataSource) class which is used for fetching data from a REST API and exposing it via GraphQL within Apollo Server.&#8221;<\/p>\n<p>* Apollo Gateway<br \/>\n&#8211; <a href=\"https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-gateway\">https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-gateway<\/a><br \/>\n&#8211; sits above other GraphQL services<\/p>\n<p>* GraphQL DataLoader<br \/>\n&#8211; <a href=\"https:\/\/github.com\/graphql\/dataloader\">https:\/\/github.com\/graphql\/dataloader<\/a><br \/>\n&#8211; &#8220;DataLoader is a generic utility to be used as part of your application&#8217;s data fetching layer to provide a consistent API over various backends and reduce requests to those backends via batching and caching.&#8221;<br \/>\n&#8211; improves performance of GraphQL service<\/p>\n<p>* Express<br \/>\n&#8211; <a href=\"https:\/\/github.com\/expressjs\/express\/\">https:\/\/github.com\/expressjs\/express\/<\/a><br \/>\n&#8211; &#8220;Fast, unopinionated, minimalist web framework for node&#8221;<br \/>\n&#8211; helps create an HTTP service quickly<\/p>\n<p>* Faker<br \/>\n&#8211; <a href=\"https:\/\/github.com\/marak\/Faker.js\/\">https:\/\/github.com\/marak\/Faker.js\/<\/a><br \/>\n&#8211; &#8220;generate massive amounts of realistic fake data in Node.js and the browser&#8221;<br \/>\n&#8211; helps create random\/mock data<\/p>\n<p>* Lerna<br \/>\n&#8211; <a href=\"https:\/\/github.com\/lerna\/lerna\">https:\/\/github.com\/lerna\/lerna<\/a><br \/>\n&#8211; &#8220;A tool for managing JavaScript projects with multiple packages.&#8221;<\/p>\n<p><strong>## List of core REST services<\/strong><\/p>\n<p>* rest-auth<br \/>\n&#8211; http:\/\/localhost:10111<br \/>\n&#8211; manages login actions, user records<\/p>\n<p>* rest-accounts<br \/>\n&#8211; http:\/\/localhost:10222<br \/>\n&#8211; manages bank accounts and transactions<\/p>\n<p>* rest-payments<br \/>\n&#8211; http:\/\/localhost:10333<br \/>\n&#8211; manages money transfers<\/p>\n<p><strong>## List of GraphQL services using Core REST services<\/strong><\/p>\n<p>* gql-fed-auth<br \/>\n&#8211; http:\/\/localhost:20111<br \/>\n&#8211; uses rest-auth<\/p>\n<p>* gql-fed-accounts<br \/>\n&#8211; http:\/\/localhost:20222<br \/>\n&#8211; uses rest-accounts<\/p>\n<p>* gql-fed-payments<br \/>\n&#8211; http:\/\/localhost:20333<br \/>\n&#8211; uses rest-payments<\/p>\n<p><strong>## Standard GraphQL service using Core REST services<\/strong><\/p>\n<p>* gql-standard<br \/>\n&#8211; http:\/\/localhost:30111<br \/>\n&#8211; uses rest-auth<br \/>\n&#8211; uses rest-accounts<br \/>\n&#8211; uses rest-payments<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Standard-480x360.jpg\" alt=\"\" width=\"480\" height=\"360\" class=\"aligncenter size-medium wp-image-1050\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Standard-480x360.jpg 480w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Standard-768x576.jpg 768w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Standard-887x665.jpg 887w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Standard.jpg 960w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p><strong>## GraphQL Gateway service<\/strong><\/p>\n<p>* gql-gateway<br \/>\n&#8211; http:\/\/localhost:40111<br \/>\n&#8211; uses gql-fed-auth<br \/>\n&#8211; uses gql-fed-accounts<br \/>\n&#8211; uses gql-fed-payments<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Gateway-480x360.jpg\" alt=\"\" width=\"480\" height=\"360\" class=\"aligncenter size-medium wp-image-1051\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Gateway-480x360.jpg 480w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Gateway-768x576.jpg 768w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Gateway-887x665.jpg 887w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/Fakebank-Architecture-GraphQL-Gateway.jpg 960w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p><strong>## Sequence diagrams<\/strong><\/p>\n<p>To see the diagrams, use <a href=\"https:\/\/sequencediagram.org\/\">https:\/\/sequencediagram.org\/<\/a><\/p>\n<p><strong>### A. GraphQL Standard<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2020\/04\/fakebank-graphql-standard-480x460.jpg\" alt=\"\" width=\"480\" height=\"460\" class=\"aligncenter size-medium wp-image-1044\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-standard-480x460.jpg 480w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-standard-768x736.jpg 768w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-standard.jpg 797w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p><code><br \/>\ntitle Fake Bank APIs with GraphQL Standard<br \/>\napp->api-gateway: request<br \/>\napi-gateway->gql-standard: request<br \/>\ngql-standard --> rest-X: request a<br \/>\nrest-X -> db-X: select data a<br \/>\nrest-X <- db-X: records a\ngql-standard <- rest-X: response a\ngql-standard --> rest-Y: request b<br \/>\nrest-Y -> db-Y: select data b<br \/>\nrest-Y <- db-Y: records b\ngql-standard <- rest-Y: response b\napi-gateway <- gql-standard: response\napp <- api-gateway: response\n<\/code><\/p>\n<p><strong>### B. GraphQL Gateway<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.muratyaman.co.uk\/wp\/wp-content\/uploads\/2020\/04\/fakebank-graphql-gateway-480x439.jpg\" alt=\"\" width=\"480\" height=\"439\" class=\"aligncenter size-medium wp-image-1045\" srcset=\"https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-gateway-480x439.jpg 480w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-gateway-768x703.jpg 768w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-gateway-887x812.jpg 887w, https:\/\/www.muratyaman.co.uk\/blog\/wp-content\/uploads\/2020\/04\/fakebank-graphql-gateway.jpg 1050w\" sizes=\"auto, (max-width: 480px) 100vw, 480px\" \/><\/p>\n<p><code><br \/>\ntitle Fake Bank APIs with GrapQL Gateway<\/p>\n<p>app->api-gateway: request<br \/>\napi-gateway->gql-gateway: request<\/p>\n<p>gql-gateway --> gql-fed-X: request a<br \/>\ngql-fed-X -> rest-X: request a<br \/>\nrest-X -> db-X: select data a<br \/>\nrest-X <- db-X: records a\ngql-fed-X <- rest-X: response a\ngql-gateway <- gql-fed-X: response a\n\ngql-gateway --> gql-fed-Y: request b<br \/>\ngql-fed-Y -> rest-Y: request b<br \/>\nrest-Y -> db-Y: select data b<br \/>\nrest-Y <- db-Y: records b\ngql-fed-Y <- rest-Y: response b\ngql-gateway <- gql-fed-Y: response b\n\napi-gateway <- gql-gateway: response\napp <- api-gateway: response\n<\/code><\/p>\n<p><strong>## Installation<\/strong><\/p>\n<p>Install yarn and lerna globally<\/p>\n<p><code><br \/>\nnpm i -g yarn lerna<br \/>\n<\/code><\/p>\n<p>Install dependencies for all packages in this codebase.<\/p>\n<p><code><br \/>\nlerna bootstrap<br \/>\n<\/code><\/p>\n<p><strong>## Build<\/strong><\/p>\n<p><code><br \/>\nlerna run build<br \/>\n<\/code><\/p>\n<p><strong>## Start in production mode<\/strong><\/p>\n<p>Run these in separate terminals in this order:<\/p>\n<p><strong>## Core REST services<\/strong><\/p>\n<p>Random\/fake data is generated at runtime<\/p>\n<p><code><br \/>\nlerna run start:prod --scope=@fakebank\/rest-auth<br \/>\nlerna run start:prod --scope=@fakebank\/rest-accounts<br \/>\nlerna run start:prod --scope=@fakebank\/rest-payments<br \/>\n<\/code><\/p>\n<p><strong>## GraphQL Services<\/strong><\/p>\n<p>These services are used by GraphQL Gateway<\/p>\n<p><code><br \/>\nlerna run start:prod --scope=@fakebank\/gql-fed-auth<br \/>\nlerna run start:prod --scope=@fakebank\/gql-fed-accounts<br \/>\nlerna run start:prod --scope=@fakebank\/gql-fed-payments<br \/>\nlerna run start:prod --scope=@fakebank\/gql-gateway<br \/>\n<\/code><\/p>\n<p><strong>## Standard GrapQL service<\/strong><\/p>\n<p>We can use RESTful services directly<\/p>\n<p><code><br \/>\nlerna run start --scope=@fakebank\/gql-standard<br \/>\n<\/code><\/p>\n<p>Note: Another way to run a service:<\/p>\n<p><code><br \/>\ncd packages\/core-auth<br \/>\nyarn start:prod<br \/>\n<\/code><\/p>\n<p>On the next post, I will discuss the details of GraphQL federation: <a href=\"https:\/\/www.muratyaman.co.uk\/wp\/index.php\/2020\/04\/federation-of-graphql-services-using-apollo-gateway\/\">Federation of GraphQL Services using Apollo Gateway<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have prepared 2 repos to implement FakeBank using GraphQL: 1. JavaScript: https:\/\/github.com\/muratyaman\/fakebank-js 2. TypeScript: https:\/\/github.com\/muratyaman\/fakebank-ts Architecture can be like this: FakeBank uses: * GraphQL &#8211; https:\/\/graphql.org\/ &#8211; &#8220;GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.&#8221; * GraphQL-JS &#8211; https:\/\/github.com\/graphql\/graphql-js &#8211; &#8220;A reference implementation of GraphQL for JavaScript&#8221; * Apollo Server &#8211; https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-server &#8211; &#8220;Apollo Server is an open-source, spec-compliant GraphQL server that&#8217;s compatible with any GraphQL client&#8221; * Apollo Federation &#8211; https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-federation &#8211; &#8220;&#8230; expose a single data graph that provides a unified interface for querying all of your backing data sources&#8221; * Apollo REST Data Source &#8211; https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-datasource-rest &#8211; &#8220;This package exports a (RESTDataSource) class which is used for fetching data from a REST API and exposing it via GraphQL within Apollo Server.&#8221; * Apollo Gateway &#8211; https:\/\/github.com\/apollographql\/apollo-server\/tree\/master\/packages\/apollo-gateway &#8211; sits above other GraphQL services * GraphQL DataLoader &#8211; https:\/\/github.com\/graphql\/dataloader &#8211; &#8220;DataLoader is a generic utility to be used as part of your application&#8217;s data fetching layer to provide a consistent API over various backends and reduce requests to those backends via batching and caching.&#8221; &#8211; improves performance of GraphQL service * Express &#8211; https:\/\/github.com\/expressjs\/express\/ &#8211; &#8220;Fast, unopinionated, minimalist web framework for node&#8221; &#8211; helps create an HTTP service quickly * Faker &#8211; https:\/\/github.com\/marak\/Faker.js\/ &#8211; &#8220;generate massive amounts of realistic fake data in Node.js and the browser&#8221; &#8211; helps create random\/mock data * Lerna &#8211; https:\/\/github.com\/lerna\/lerna &#8211; &#8220;A tool for managing JavaScript projects with multiple packages.&#8221; ## List of core REST services * rest-auth &#8211; http:\/\/localhost:10111 &#8211; manages login actions, user records * rest-accounts &#8211; http:\/\/localhost:10222 &#8211; manages bank accounts and transactions * rest-payments &#8211; http:\/\/localhost:10333 &#8211; manages money transfers ## List of GraphQL services using Core REST services * gql-fed-auth &#8211; http:\/\/localhost:20111 &#8211; uses rest-auth * gql-fed-accounts &#8211; http:\/\/localhost:20222 &#8211; uses rest-accounts * gql-fed-payments &#8211; http:\/\/localhost:20333 &#8211; uses rest-payments ## Standard GraphQL service using Core REST services * gql-standard &#8211; http:\/\/localhost:30111 &#8211; uses rest-auth &#8211; uses rest-accounts &#8211; uses rest-payments ## GraphQL Gateway service * gql-gateway &#8211; http:\/\/localhost:40111 &#8211; uses gql-fed-auth &#8211; uses gql-fed-accounts &#8211; uses gql-fed-payments ## Sequence diagrams To see the diagrams, use https:\/\/sequencediagram.org\/ ### A. GraphQL Standard title Fake Bank APIs with GraphQL Standard app->api-gateway: request api-gateway->gql-standard: request gql-standard &#8211;> rest-X: request a rest-X -> db-X: select data a rest-X db-Y: select data b rest-Y rest-X: request a rest-X -> db-X: select data a rest-X db-Y: select data b rest-Y<\/p>\n","protected":false},"author":2,"featured_media":1049,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[200,93,166,201],"class_list":["post-1042","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology","tag-graphql","tag-javascript","tag-node","tag-typescript"],"_links":{"self":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1042","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1042"}],"version-history":[{"count":6,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1042\/revisions"}],"predecessor-version":[{"id":1057,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1042\/revisions\/1057"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media\/1049"}],"wp:attachment":[{"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.muratyaman.co.uk\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}