Hacker News new | ask | show | jobs
by BradRuderman 4155 days ago
In my experience the biggest frustration when building microservices is the replicated logic across multiple languages/frameworks. For example if my microservices are in node/io.js and my app a rails app, then I can't replicate my model logic in my node services. Have you done anything in the jolie language to help this problem?
3 comments

> For example if my microservices are in node/io.js and my app a rails app, then I can't replicate my model logic in my node services.

Why would you want to do this? If something is the responsibility of one service, why is another service or app duplicating its logic?

Perhaps several layers of input data validation? Typically the problem is that you want the client side (ie: javascript) to do form validation for early-feedback to the user, and the back-end to do actual input filtering/validation -- but I suppose one might want to push input-errors/validation-errors as far out towards the input as possible -- also in case of a web of micro-services? Things like allowing only utf8, or maintaining data integrity for relationships (eg: in order to add dependants to a person, those need to be defined with some kind of minimal data, like a social security number?).

I am a bit puzzled as well -- I normally think of this as a problem of synchronizing back-end and front-end -- but then again, if you have a proper SQL-schema, with a thin REST-layer abstraction/API on top, you'd probably have to have other services know about your models in order to do input-validation before attempting to post/insert/update data?

What we can do right now is having a microservice for input validation and call it when we need to validate something, both from the client and the server parts. In Jolie, adding calls to a validator for all functionalities exposed by a microservice is easy with courier constructs (http://docs.jolie-lang.org/#!documentation/architectural_com...).

However, if your client application is a web app, that may mean generating a lot of traffic between clients and web server.

In theory, we could make a tool for automatically propagating validation checking from Jolie to client code, but that's a hard problem because some checks depend on information that only the server knows, so sometimes you need to make remote calls anyway. Not all hope is lost, because in many cases a static analysis could tell us what can be safely exported to the client and what cannot.

I am not sure I understood well the question but I hope this answer could help you. Usually in Jolie we proceed as follows: - the logic (the one which should be replicated) is served by one microservice (which could be embedded or deployed separately, it doesn't matter). Let me call it L. - the other entities which requires that logic just invoke the microservice L - in the case of the web app, we use Leonardo (http://sourceforge.net/projects/leonardo/), which is a web server written in pure Jolie, we public the calls to L by simply adding them in few lines of code through aggregation. In this case Leonardo, which serves the http protocol, just take the message, transform it in another protocol (we usually exploit sodep for Jolie to Jolie communication) and redirect the message to L which exectues the logic.
So... the code[1] for Leonardo is certainly short and sweet -- but is this considered a production-grade web server? I doesn't appear to do anything in parallel (no "|" in the code, anyway) -- is this a thin wrapper around something more robust in the Jolie standard lib/run-time?

[1] http://sourceforge.net/p/leonardo/code/HEAD/tree/trunk/leona...

If not Leonardo -- is there some production-quality, yet simple, code that one could look at to get a feel for how an actual Jolie service might look? Say a micro-blogging site or something?

Always interesting to see new languages and platforms!

Leonardo is almost production ready, we usually just add some lines to tune the caching parameters as needed.

This is the code for the Jolie website if you're curious about an example:

https://sourceforge.net/p/jolie/code/HEAD/tree/web/trunk/jol...

We launch leonardo/leonardo.ol on the server.

The reason for which Leonardo works is that "execution { concurrent }" line which tells Jolie to start a new (light) process whenever a top-level operation is invoked. In this case we have only default, a catch-all operation for serving requests for files. So each time a client invokes Leonardo, a new process handles the request. Jolie processes are implemented as threads (cached in a thread pool when possible) with a local state (no data sharing, only communications).

Notice that in Leonardo we are embedding frontend.ol, which means that it will be run as a sub-service. And we also aggregate it in the HTTP input port, which means that its operations become available to clients. So now clients can not only invoke the catch-all default operation, but also the operations in frontend.ol.

Looking at frontend.ol, you will find one of these operation, e.g., "news". That's what you access when you go to http://www.jolie-lang.org/news

What does it do? It uses another sub-(micro)service, a blog reader, to fetch blog entries from our news blog, and then displays it to the user.

It's all a bit crude, in the enterprise we don't usually build html from scratch, but the Jolie website was so simple that we just went for it.

It may be the late hour here (CET), but I only kinda understood your question. What do you mean by "I can't replicate my model logic in my node services" ?
I think by "model logic" he is referring to MVC and things like data model relationships (and an ORM possibly), validation/casting, etc.

For example, in a single programming language and framework you could say:

payment.isPayPay()

from a payment out of a database wrapped into a model.

It has not been traditionally easy to share that business logic across languages (and by easy I mean not wrapping huge numbers of methods in http requests).

This is correct. Business logic that exists in the model methods like in an MVC framework talking to backend services. When you have micro services in general you tend to have logic replicated in all the different micro services and even the consumers of those services.
Thanks, I get it now.

If you use Jolie for implementing MVC, then every component is automatically a microservice (by construction from the language) and you can reuse them very easily in Jolie, Java, and Javascript inside of web browsers.

If you use other languages:

- if you need to use logic handled by a Jolie microservice, then you just need an API for making remote calls to that microservice. Jolie provides HTTP/JSON, HTTP/XML, SOAP, SODEP, XML-RPC, Java RMI, HTTP/GWT, and others. We have native libraries in Java (also usable in Scala) for making it even easier and look more native. You do not need to consider which protocol you will use in your logic, Jolie separates data format from logic by design. So it boils down to how easy it is to make remote calls in the "client" language.

- if you have programmed your logic in another language, you will need to expose it somehow to Jolie. If you use Java or Javascript, we can reuse it natively or almost natively. Otherwise, you will need to expose the functionalities using one of the protocols above, then Jolie will immediately see it as a native service as if it were implemented in Jolie (we make no difference between stuff implemented in Jolie or not if you support any of our communication means).

Is this a satisfactory answer? We can dive into examples if you have something specific in mind.