Oregon State University|blogs.oregonstate.edu
Blog Owner
Blogger Name

Regret Regret Regret

  October 22nd, 2021
Prophet of Regret | Characters | Universe | Halo - Official Site

Regret is a strong word. I have regrets. Monoliths have their advantages, and I am rapidly and repeatedly finding them as I implement a microservice ecosystem for the first time. This week I set out to define the gateway API and dummy routes in the user service to experiment with multi-layer API calls. Then I sat down and realized that in order to talk to each other, the services each needed to know where the others were. I could hardcode URLs and rely on everything working perfectly and never changing; you already know why that’s a bad idea. I could have the gateway service pull double duty and have it’s address hardcoded into all other services; this would disobey a core principle of microservice philosophy and not actually save any trouble vs doing it properly.

Pooh Bear Quotes About Thinking. QuotesGram

So I now have a new coordinator service which will have its address provided via config files in all the other microservices and will be queried to retrieve the URLs for services of interest. I also got to learn how to create and use a custom Node module in order to keep to DRY principles; if every microservice is going to need to talk to the coordinator, then there needs to be a standardized block of code that I don’t need to worry about fixing everywhere any time it needs a fix.

Starting with the module, it turns out that the basic documentation is really all that was needed to actually do the module-specific pieces, although what they don’t tell you is that the ability to publish a private module requires a premium subscription. The module code was also pretty simple; private variables to store the needed URLs, setters for the coordinator URL and other service URLs, and two layers of getters for a service URL – if it is already stored and by making a query to the coordinator if it isn’t. Testing is where the real fun was. I finally got to knock out some Nock, and I had to pull on a new tutorial on top of what I’ve linked in the past. Setting up the dummy routes wasn’t actually so bad, but interfacing it with Chai and the request module proved to be a hassle. Request has been deprecated, so I needed to sift through a decade of now out of date information, the HTTPS just did not give me any compatible output, and so I settled on Axios as a module that I’ve used in the past. Even then, it took a couple hours of trial and error with the Chai documentation to get the async tests to validate correctly without timing out.

Then there was the matter of the coordinator service itself. Again, easy to code but a pain to figure out correct testing. There’s just the GETter and SETer routes and supporting model functions but I still don’t have a handle on Chai. Several timeouts, errors, and false test passes later I got to here:

describe('/POST service', function() {
it('should return a 201 status with self address attached', function(done) {
        chai.request(app)
            .post('/services/' + serviceName)
            .end((err, res) => {
                res.should.have.status(201);
                let address = res.body[serviceName];
                address.substr(0, address.indexOf(":")).should.be.an.ip;
                done();
            });
    });
});

The major lessons learned to make it work:

  • You can’t use an arrow function (() => {}) with Chai and keep things stable due to binding.
  • Without a done() an async function will time out
  • An address with a port number does not register as an IP address in Chai
  • Anything can be solved with judicious use of string manipulation
If it looks stupid but works.. it ain't stupid | Picture Quotes

Once there was a module and coordinator service to test with, it was time to make an experimental service to use the module and talk to the coordinator. Again with the testing woes. I ended up refactoring the module to export a class rather than a collection of functions, which also solved the issue of assuming globality – each router file can safely have its own copy of the URL completer without much overhead. Once that was done, I was able to pretty much copy over the (also refactored) tests from the module into my experimental service. As of now I haven’t actually done an integration test for the services, so it might all need to be fixed again once I try running them together.

Just when I thought I was done with my re-figured week, I got to learn a whole new thing: working with SSH keys in GitHub actions. I’ll let you know how that all works out next week, but so far it’s been more ‘trying things and having them not work’.

Culture Connoisseur: A Severe Case of Headdesk
Print Friendly, PDF & Email

Leave a Reply