paint-brush
Իմ GraphQL հմտությունների մակարդակի բարձրացում. իրական ժամանակի բաժանորդագրություններկողմից@johnjvester
488 ընթերցումներ
488 ընթերցումներ

Իմ GraphQL հմտությունների մակարդակի բարձրացում. իրական ժամանակի բաժանորդագրություններ

կողմից John Vester10m2024/09/18
Read on Terminal Reader

Չափազանց երկար; Կարդալ

Մի փոքր խորացեք՝ ուսումնասիրելու իրական ժամանակի տվյալների բաժանորդագրությունները՝ օգտագործելով GraphQL՝ WebSocket-ի սպառողի օգնությամբ ավտոմատ կերպով սերվերի կողմից թարմացումներ ստանալու համար:
featured image - Իմ GraphQL հմտությունների մակարդակի բարձրացում. իրական ժամանակի բաժանորդագրություններ
John Vester HackerNoon profile picture

Արդեն մի քանի տարի է, ես փորձել եմ բացահայտել շրջանակներ, ապրանքներ և ծառայություններ, որոնք թույլ են տալիս տեխնոլոգներին պահպանել իրենց ուշադրությունը իրենց մտավոր սեփականության արժեքի ընդլայնման վրա: Սա ինձ համար շարունակում է մնալ հրաշալի ճանապարհորդություն՝ լի եզակի ուսուցման հնարավորություններով:


Ինժեները իմ մեջ վերջերս մտածեց, թե արդյոք կա մի իրավիճակ, որտեղ ես կարող եմ երկրորդական օգուտ գտնել գոյություն ունեցող հայեցակարգի համար, որի մասին ես նախկինում խոսել եմ: Այլ կերպ ասած, ես կարո՞ղ եմ բացահայտել մեկ այլ օգուտ նույն ազդեցության մակարդակով, ինչ նախկինում ճանաչված սկզբնական մայր լուծումը:


Այս հոդվածի համար ես ուզում էի ավելի խորանալ GraphQL-ի մեջ՝ տեսնելու, թե ինչ կարող եմ գտնել:


Իմ « Երբ հանգստանալու ժամանակն է » հոդվածում ես խոսեցի այն մասին, թե ինչպես կան իրական աշխարհի սցենարներ, երբ GraphQL-ը գերադասելի է RESTful ծառայության փոխարեն: Մենք քայլեցինք, թե ինչպես կարելի է կառուցել և տեղակայել GraphQL API՝ օգտագործելով Apollo Server:


Այս հաջորդական գրառման մեջ ես նախատեսում եմ բարձրացնել իմ գիտելիքները GraphQL-ի մասին՝ անցնելով իրական ժամանակում տվյալների որոնման բաժանորդագրությունների միջով: Մենք նաև կկառուցենք WebSocket ծառայություն՝ բաժանորդագրությունները սպառելու համար:

Recap. Customer 360 Use Case

Իմ նախորդ հոդվածը կենտրոնացած էր Հաճախորդ 360 օգտագործման դեպքի շուրջ, որտեղ իմ հորինված բիզնեսի հովանավորները պահպանում են հետևյալ տվյալների հավաքածուները.


  • Հաճախորդի տեղեկատվություն
  • Հասցեի տվյալներ
  • Կապի մեթոդներ
  • Վարկային հատկանիշներ


GraphQL-ի օգտագործման հսկայական հաղթանակն այն է, որ մեկ GraphQL հարցումը կարող է առբերել հաճախորդի նշանի համար անհրաժեշտ բոլոր տվյալները (եզակի ինքնություն):


 type Query { addresses: [Address] address(customer_token: String): Address contacts: [Contact] contact(customer_token: String): Contact customers: [Customer] customer(token: String): Customer credits: [Credit] credit(customer_token: String): Credit }


Հաճախորդի մեկ (360) տեսակետը ստանալու համար RESTful մոտեցման օգտագործումը կպահանջի մի քանի հարցումների և պատասխանների համադրում: GraphQL-ը մեզ լուծում է տալիս, որը շատ ավելի լավ է աշխատում:

Մակարդակի բարձրացման նպատակներ

Կյանքի ցանկացած բնագավառում մակարդակը բարձրանալու համար պետք է հասնել նոր նպատակների: Իմ սեփական նպատակների համար այստեղ սա նշանակում է.


  • GraphQL-ում բաժանորդագրության արժեքի առաջարկի ըմբռնում և իրականացում:
  • Օգտագործելով WebSocket ներդրումը GraphQL բաժանորդագրությունը սպառելու համար:


GraphQL հարցումների և մուտացիաների վրա բաժանորդագրություններ օգտագործելու գաղափարը նախընտրելի մեթոդ է, երբ բավարարվում են հետևյալ պայմանները.


  • Փոքր, աստիճանական փոփոխություններ մեծ օբյեկտների նկատմամբ
  • Ցածր հետաձգման, իրական ժամանակի թարմացումներ (օրինակ՝ զրույցի հավելված)


Սա կարևոր է, քանի որ GraphQL-ի ներսում բաժանորդագրություններ իրականացնելը մանրուք չէ: Ոչ միայն հիմքում ընկած սերվերը պետք է թարմացվի, այլև սպառող հավելվածը կպահանջի որոշակի վերանախագծում:


Բարեբախտաբար, օգտագործման դեպքը, որը մենք հետապնդում ենք մեր Հաճախորդ 360 օրինակով, հիանալի հարմար է բաժանորդագրությունների համար: Բացի այդ, մենք կիրականացնենք WebSocket մոտեցում՝ այդ բաժանորդագրությունները օգտագործելու համար:


Ինչպես նախկինում, ես կշարունակեմ օգտագործել Apollo-ն առաջ գնալով:

Բաժանորդագրության վարկերի մակարդակի բարձրացում

Նախ, մենք պետք է տեղադրենք անհրաժեշտ գրադարանները՝ իմ Apollo GraphQL սերվերով բաժանորդագրություններն աջակցելու համար.


 npm install ws npm install graphql-ws @graphql-tools/schema npm install graphql-subscriptions


Տեղադրված այդ տարրերով ես կենտրոնացա index.ts թարմացման վրա իմ սկզբնական պահոցից՝ ընդլայնելու typedefs հաստատունը հետևյալով.


 type Subscription { creditUpdated: Credit }


Ես նաև հաստատեցի նոր PubSub օրինակը տեղադրելու համար և ստեղծեցի բաժանորդագրության նմուշ, որը մենք հետագայում կօգտագործենք.


 const pubsub = new PubSub(); pubsub.publish('CREDIT_BALANCE_UPDATED', { creditUpdated: { } });


Ես մաքրեցի առկա լուծիչները և ավելացրի նոր Subscription այս նոր օգտագործման դեպքի համար.


 const resolvers = { Query: { addresses: () => addresses, address: (parent, args) => { const customer_token = args.customer_token; return addresses.find(address => address.customer_token === customer_token); }, contacts: () => contacts, contact: (parent, args) => { const customer_token = args.customer_token; return contacts.find(contact => contact.customer_token === customer_token); }, customers: () => customers, customer: (parent, args) => { const token = args.token; return customers.find(customer => customer.token === token); }, credits: () => credits, credit: (parent, args) => { const customer_token = args.customer_token; return credits.find(credit => credit.customer_token === customer_token); } }, Subscription: { creditUpdated: { subscribe: () => pubsub.asyncIterator(['CREDIT_BALANCE_UPDATED']), } } };


Այնուհետև ես վերամշակեցի սերվերի կոնֆիգուրացիան և ներկայացրեցի բաժանորդագրության դիզայնը.


 const app = express(); const httpServer = createServer(app); const wsServer = new WebSocketServer({ server: httpServer, path: '/graphql' }); const schema = makeExecutableSchema({ typeDefs, resolvers }); const serverCleanup = useServer({ schema }, wsServer); const server = new ApolloServer({ schema, plugins: [ ApolloServerPluginDrainHttpServer({ httpServer }), { async serverWillStart() { return { async drainServer() { serverCleanup.dispose(); } }; } } ], }); await server.start(); app.use('/graphql', cors(), express.json(), expressMiddleware(server, { context: async () => ({ pubsub }) })); const PORT = Number.parseInt(process.env.PORT) || 4000; httpServer.listen(PORT, () => { console.log(`Server is now running on http://localhost:${PORT}/graphql`); console.log(`Subscription is now running on ws://localhost:${PORT}/graphql`); });


Հաճախորդների վրա հիմնված թարմացումները մոդելավորելու համար ես ստեղծեցի հետևյալ մեթոդը՝ ծառայության գործարկման ընթացքում յուրաքանչյուր հինգ վայրկյանը մեկ վարկային մնացորդը $50-ով ավելացնելու համար: Երբ մնացորդը հասնում է (կամ գերազանցում է) $10,000 վարկային սահմանաչափը, ես վերականգնում եմ մնացորդը մինչև $2,500՝ նմանակելով մնացորդի վճարումը:


 function incrementCreditBalance() { if (credits[0].balance >= credits[0].credit_limit) { credits[0].balance = 0.00; console.log(`Credit balance reset to ${credits[0].balance}`); } else { credits[0].balance += 50.00; console.log(`Credit balance updated to ${credits[0].balance}`); } pubsub.publish('CREDIT_BALANCE_UPDATED', { creditUpdated: credits[0] }); setTimeout(incrementCreditBalance, 5000); } incrementCreditBalance();


Ամբողջական index.ts ֆայլը կարող եք գտնել այստեղ :

Տեղադրեք Հերոկու

Ծառայությունը պատրաստ լինելու դեպքում ժամանակն է, որ մենք գործարկենք ծառայությունը, որպեսզի կարողանանք շփվել դրա հետ: Քանի որ Հերոկուն անցյալ անգամ հիանալի աշխատեց (և ինձ համար հեշտ է օգտագործել), եկեք մնանք այդ մոտեցմանը:


Սկսելու համար ես պետք է գործարկեի հետևյալ Heroku CLI հրամանները.


 $ heroku login $ heroku create jvc-graphql-server-sub Creating ⬢ jvc-graphql-server-sub... done https://jvc-graphql-server-sub-1ec2e6406a82.herokuapp.com/ | https://git.heroku.com/jvc-graphql-server-sub.git


Հրամանը նաև ավտոմատ կերպով ավելացրել է Հերոկուի կողմից որպես հեռակառավարվող պահոց.


 $ git remote heroku origin


Ինչպես ես նշել եմ իմ նախորդ հոդվածում, Apollo Server-ը անջատում է Apollo Explorer-ը արտադրական միջավայրերում: Որպեսզի Apollo Explorer-ը հասանելի լինի մեր կարիքների համար, ես պետք է սահմանեի NODE_ENV միջավայրի փոփոխականը զարգացման համար: Ես դա սահմանեցի հետևյալ CLI հրամանով.


 $ heroku config:set NODE_ENV=development Setting NODE_ENV and restarting ⬢ jvc-graphql-server-sub... done, v3 NODE_ENV: development


Ես պատրաստ էի տեղակայել իմ կոդը Հերոկուում.


 $ git commit --allow-empty -m 'Deploy to Heroku' $ git push heroku


Heroku Dashboard-ի արագ տեսքը ցույց տվեց, որ իմ Apollo սերվերը աշխատում է առանց որևէ խնդիրների.


Կարգավորումների բաժնում ես գտա Heroku հավելվածի URL-ը այս ծառայության օրինակի համար.


https://jvc-graphql-server-sub-1ec2e6406a82.herokuapp.com/


Խնդրում ենք նկատի ունենալ. այս հղումն այլևս չի գործի մինչև այս հոդվածը հրապարակվի:


Առայժմ ես կարող եմ GraphQL-ն ավելացնել այս URL-ին՝ Apollo Server Studio-ին գործարկելու համար: Սա թույլ կտա ինձ տեսնել, որ բաժանորդագրությունները աշխատում են այնպես, ինչպես սպասվում էր.


Ուշադրություն դարձրեք Բաժանորդագրության պատասխաններին էկրանի աջ կողմում:

Հարթեցում WebSocket Skillz-ի միջոցով

Մենք կարող ենք օգտագործել WebSocket-ի աջակցությունը և Heroku-ի հնարավորությունները՝ ստեղծելու այնպիսի իրականացում, որը սպառում է մեր ստեղծած բաժանորդագրությունը:


Իմ դեպքում ես ստեղծեցի index.js ֆայլ հետևյալ բովանդակությամբ. Ըստ էության, սա ստեղծեց WebSocket հաճախորդ, ինչպես նաև ստեղծեց կեղծ HTTP ծառայություն, որը ես կարող էի օգտագործել՝ հաստատելու, որ հաճախորդն աշխատում է.


 import { createClient } from "graphql-ws"; import { WebSocket } from "ws"; import http from "http"; // Create a dummy HTTP server to bind to Heroku's $PORT const PORT = process.env.PORT || 3000; http.createServer((req, res) => res.end('Server is running')).listen(PORT, () => { console.log(`HTTP server running on port ${PORT}`); }); const host_url = process.env.GRAPHQL_SUBSCRIPTION_HOST || 'ws://localhost:4000/graphql'; const client = createClient({ url: host_url, webSocketImpl: WebSocket }); const query = `subscription { creditUpdated { token customer_token credit_limit balance credit_score } }`; function handleCreditUpdated(data) { console.log('Received credit update:', data); } // Subscribe to the creditUpdated subscription client.subscribe( { query, }, { next: (data) => handleCreditUpdated(data.data.creditUpdated), error: (err) => console.error('Subscription error:', err), complete: () => console.log('Subscription complete'), } );


Ամբողջական index.js ֆայլը կարող եք գտնել այստեղ :


Մենք կարող ենք այս պարզ Node.js հավելվածը տեղակայել նաև Heroku-ում, համոզվելով, որ GRAPHQL_SUBSCRIPTION_HOST միջավայրի փոփոխականը սահմանել ենք Heroku հավելվածի URL-ին, որը մենք նախկինում օգտագործել ենք:


Ես նաև ստեղծեցի հետևյալ Procfile Հերոկուին պատմելու համար, թե ինչպես գործարկել իմ հավելվածը.


 web: node src/index.js


Հաջորդը, ես ստեղծեցի նոր Heroku հավելված.


 $ heroku create jvc-websocket-example Creating ⬢ jvc-websocket-example... done https://jvc-websocket-example-62824c0b1df4.herokuapp.com/ | https://git.heroku.com/jvc-websocket-example.git


Այնուհետև ես սահմանեցի GRAPHQL_SUBSCRIPTION_HOST միջավայրի փոփոխականը, որպեսզի մատնանշի իմ աշխատող GraphQL սերվերը.


 $ heroku --app jvc-websocket-example \ config:set \ GRAPHQL_SUBSCRIPTION_HOST=ws://jvc-graphql-server-sub-1ec2e6406a82.herokuapp.com/graphql


Այս պահին մենք պատրաստ ենք մեր կոդը տեղակայել Հերոկուում՝


 $ git commit --allow-empty -m 'Deploy to Heroku' $ git push heroku


WebSocket հաճախորդը սկսելուց հետո մենք կարող ենք տեսնել դրա կարգավիճակը Heroku Dashboard-ում.


Դիտելով Heroku Dashboard-ի տեղեկամատյանները jvc-websocket-example օրինակի համար՝ մենք կարող ենք տեսնել jvc-graphql-server-sub ծառայության balance հատկության բազմաթիվ թարմացումները: Իմ ցուցադրությունում ես նույնիսկ կարողացա ֆիքսել օգտագործման դեպքը, երբ մնացորդը զրոյի է հասցվել՝ նմանակելով, որ վճարում է կատարվել.


Տերմինալում մենք կարող ենք մուտք գործել այդ նույն տեղեկամատյանները CLI հրամանի heroku տեղեկամատյաններով:


 2024-08-28T12:14:48.463846+00:00 app[web.1]: Received credit update: { 2024-08-28T12:14:48.463874+00:00 app[web.1]: token: 'credit-token-1', 2024-08-28T12:14:48.463875+00:00 app[web.1]: customer_token: 'customer-token-1', 2024-08-28T12:14:48.463875+00:00 app[web.1]: credit_limit: 10000, 2024-08-28T12:14:48.463875+00:00 app[web.1]: balance: 9950, 2024-08-28T12:14:48.463876+00:00 app[web.1]: credit_score: 750 2024-08-28T12:14:48.463876+00:00 app[web.1]: }


Մենք ոչ միայն ունենք GraphQL ծառայություն, որն աշխատում է բաժանորդագրության ներդրմամբ, այլև այժմ ունենք WebSocket հաճախորդ, որն օգտագործում է այդ թարմացումները:

Եզրակացություն

Իմ ընթերցողները կարող են հիշել իմ անձնական առաքելության հայտարարությունը, որը, կարծում եմ, կարող է կիրառել ցանկացած ՏՏ մասնագետի համար.


«Ձեր ժամանակը կենտրոնացրեք ձեր մտավոր սեփականության արժեքը ընդլայնող առանձնահատկություններ/ֆունկցիոնալություն տրամադրելու վրա: Մյուս ամեն ինչի համար օգտագործեք շրջանակներ, ապրանքներ և ծառայություններ»: — Ջ.Վեսթեր


GraphQL-ի բաժանորդագրությունների այս խորը ուսումնասիրության ընթացքում մենք հաջողությամբ սպառել ենք Heroku-ում աշխատող Apollo սերվերի թարմացումները՝ օգտագործելով մեկ այլ ծառայություն, որը նույնպես գործում է Heroku-ի վրա՝ Node.js-ի վրա հիմնված հավելված, որն օգտագործում է WebSockets: Օգտագործելով թեթև բաժանորդագրությունները՝ մենք խուսափեցինք անփոփոխ տվյալների համար հարցումներ ուղարկելուց, այլ պարզապես բաժանորդագրվեցինք՝ ստանալու վարկային մնացորդի թարմացումները, երբ դրանք տեղի էին ունենում:


Ներածությունում ես նշեցի, որ որոնել լրացուցիչ արժեքային սկզբունք այն թեմայի ներսում, որի մասին նախկինում գրել եմ: GraphQL բաժանորդագրությունները հիանալի օրինակ են այն ամենի, ինչ ես ունեի, քանի որ այն թույլ է տալիս սպառողներին անմիջապես թարմացումներ ստանալ՝ առանց աղբյուրի տվյալների դեմ հարցումներ անելու անհրաժեշտության: Սա շատ կհուզի Հաճախորդ 360-ի տվյալների սպառողներին՝ իմանալով, որ նրանք կարող են թարմացումներ կատարել, ինչպես դրանք տեղի են ունենում:


Heroku-ն ևս մեկ օրինակ է, որը շարունակում է հավատարիմ մնալ իմ առաքելության հայտարարությանը` առաջարկելով հարթակ, որն ինձ հնարավորություն է տալիս արագորեն նախատիպել լուծումները՝ օգտագործելով CLI և ստանդարտ Git հրամանները: Սա ոչ միայն ինձ հեշտ միջոց է տալիս ցուցադրելու իմ բաժանորդագրության օգտագործման դեպքը, այլև WebSockets օգտագործող սպառողին իրականացնելու համար:


Եթե ձեզ հետաքրքրում է այս հոդվածի սկզբնական կոդը, ստուգեք իմ պահեստները GitLab-ում.



Ես վստահ եմ զգում, երբ ասում եմ, որ այս ջանքերով ես հաջողությամբ բարձրացրել եմ իմ GraphQL հմտությունները: Այս ճամփորդությունն ինձ համար նոր և դժվար էր… և նաև շատ զվարճալի:


Հաջորդիվ ես նախատեսում եմ սուզվել նույնականացման մեջ, ինչը, հուսով եմ, ևս մեկ հնարավորություն է տալիս մակարդակի բարձրանալու GraphQL-ի և Apollo Server-ի հետ: Հետևե՛ք:


Ունեցեք իսկապես հիանալի օր: