3

I have 3 domains configured in my nodeJS app. api.example.com, www.example.com, admin.example.com To build this app in SOA way, I have different routes for API front and admin. so for routes www.example.com/myAddresses/{customerId}

var httpProxy = require('http-proxy');

var proxy = new httpProxy.RoutingProxy();

app.get('/myAddresses/:customerId, function(request, response) {

    // I can use express proxy to call API.
    proxy.proxyRequest(req, res ,{
        host: 'api.example.com',
        port: 80
    });

});

The problem with proxy I see that is proxy makes an HTTP request, which is an extra overhead. I'd like to make an internal code call.

A great implementation for same I have seen with Laravel using a package DINGO You can make an static function call in laravel like Dingo::API('/myAddresses', $request) Can anyone point me right direction to implement this feature?

EDIT

So I am already using the given approach by @Krzysztof Sztompka. I'll explain this more. My Express JS app has three subapps api, front & admin. In each module I have three sections for routes and controllers for each app respectively. Now the idea may not be only to call one route of app from same app, e.g. front route --> front route.

I only want to call Route of API app from web/admin apps. calling a function of a model is not a problem but as Krzysztof rightly said it won't be SOA approach. If you guys can just help me how to call route (and if possible call route of different app) from my controller that would be a great help.

SAM
  • 641
  • 2
  • 16
  • 30
  • Is this at all what you are trying to do? http://stackoverflow.com/a/22724122/1023812 – Ben Harold Jan 19 '16 at 15:56
  • @BenHarold this is partially what I am trying to do. The example that I have give is very basic. My entire code lies in a controller. Ideally the controller will call several APIs to get data and pass to view. So its not just a request forwarding. e.g. My example in controller can first verify the `customerId` using and API and then call API to get customer Addresses. – SAM Jan 19 '16 at 16:04

1 Answers1

2

How I do this:

  1. your routes should be something like thin clients, only wrappers for your logic modules.
  2. create logic modules in each service.
  3. this logic modules accepts parameters.
  4. Parameters are obtained in routes and passed to your logic modules
  5. Your logic modules return some data, values or just status.
  6. Router send response from server based on logic modules data.

It could looks like :

logic module file Product.js

module.exports = {
  findProduct: function (productId) { 
    ...
    return {//product data object};

  },
  getList: function (filters) { ... }
  ... 
}

and router file :

//your code to get logic module (I will write about it a little more below)

app.get('/product/:productId, function(request, response) {
  var productData = Product.findProduct(request.params.productId);
  response.send(productData);
}

First thing it is important to not pass to your logic module 'req', 'res' objects. You pass only needed values. Then your app will be testable. For unit tests you could use your logic files and pass values and check responses. Response from server you do in route, based on logic module response.

And now, is up to you how you use logic from one service to another. You could share directly logic modules, but then this is not SOA architecture. You can write some abstract access methods to communicate with other services logic. You could write similar to laravel object to manage logic modules.

In one router you could use multiple logic modules and many of their methods. Now your logic is reusable :)

Edit: OP asked about communication between services

I don't want to duplicate other questions and answers, therefore for some details please read this answer: https://stackoverflow.com/a/15139663/4138339

I think that services should communicate in normalized way. Communication between services in one server should be identical as communication between services in different servers. Therefore i prefer http calls. For http calls you can use https://github.com/request/request .

You could also use sockets to communicate.

If you want to communicate without http calls and all services are in one server then you could threat your services as one server app which create for each service new process. About communication between processes you could read more here: https://stackoverflow.com/a/10213756/4138339 But I think that this is not exactly SOA architecture. You could also

Community
  • 1
  • 1
Krzysztof Sztompka
  • 7,066
  • 4
  • 33
  • 48
  • Please see my Edit above – SAM Jan 20 '16 at 11:56
  • So this suggest calling inter-process or inter-app functions is not really out of the box supported. Proxies and Sockets can rescue us in this scenario. However I may have found a way. What if I can get an instance of handler for a route. I can get routes calling `app._router.stack`. This give me `path` which is end point. if from same Json node I can get an instance/definition of handler I may call it, using a middle-ware and mimic laravel Dingo's implementation. Any help there? – SAM Jan 21 '16 at 07:13
  • 1
    In SOA I assume that I can add new services, and this services can be written in any technology. In your proposition you assume that each service is in node.js and stand on same server. And it's a bit limited. But if you need this solution then I think that last paragraph in my answer is about, how you can get instances of each node service and how they can communicate. – Krzysztof Sztompka Jan 21 '16 at 08:38