Service discovery — find and connect to services dynamically.
1const Consul = require("consul");23class ServiceDiscovery {4 constructor() {5 this.consul = new Consul();6 this.cache = new Map();7 }89 async register(name, address, port) {10 await this.consul.agent.service.register({11 name,12 address,13 port,14 check: {15 http: `http://${address}:${port}/health`,16 interval: "10s",17 },18 });19 }2021 async discover(name) {22 const cached = this.cache.get(name);23 if (cached && Date.now() - cached.timestamp < 5000) {24 return cached.instances;25 }2627 const instances = await this.consul.health.service(name, {28 passing: true,29 });3031 const healthy = instances32 .filter(i => i.Service.Meta.healthy !== "false")33 .map(i => ({34 address: i.Service.Address,35 port: i.Service.Port,36 }));3738 this.cache.set(name, {39 instances: healthy,40 timestamp: Date.now(),41 });4243 return healthy;44 }4546 async getUrl(serviceName, path) {47 const instances = await this.discover(serviceName);48 if (!instances.length) throw new Error("No instances");49 const instance = instances[Math.floor(Math.random() * instances.length)];50 return `http://${instance.address}:${instance.port}${path}`;51 }52}5354// Usage55const discovery = new ServiceDiscovery();56await discovery.register("user-service", "localhost", 3001);5758const url = await discovery.getUrl("user-service", "/users");59const response = await fetch(url);