pnxtech / hydra-router

A service aware router for Hydra Services. Implements an API Gateway and can route web socket messages.
MIT License
60 stars 24 forks source link

Creating an API Gateway #124

Closed zerefel closed 7 years ago

zerefel commented 7 years ago

Hello, first of all I want to thank you for this awesome module. This is a general question, asking for guidance, not really an issue, I apologize if it's not the right place to ask. I couldn't figure this out after going through the entire documentation.

I am using hydra-express to build a microservices architecture, which will consist of ~15 microservices, all running behind an API Gateway. The services will communicate between each other via UMF messages.

I am wondering how one would go about implementing a centralized API gateway, which will accept all API requests and send them to the service responsible for managing them. The idea is to not allow external access to any service other than the API gateway.

Let's say I have a service called emailer and I want to route all traffic which comes to the API Gateway's route /api/emailer/* to the emailer service. From there, the service picks up the request and maps it to the corresponding internal route handler.

I am really looking forward to using this module in production with Docker. Thanks!

cjus commented 7 years ago

@zerefel Hydra-router expects this route format: /v1/emailer/

To see a working example consider these examples:

Also consider joining our slack channel where you can ask questions for our growing group of members.

https://fwsp-hydra.slack.com To join, email cjus34@gmail.com with your desired username and email address (for invite).

zerefel commented 7 years ago

@cjus Thanks for responding so fast! I looked into the examples and I am not sure that we're on the same page. Let me explain a bit further:

I have the following setup (pseudo code):

// API Gateway service

const hydraSettings = {
    "hydra": {
    "serviceName": "gateway",
    "serviceIP": "",
    "servicePort": 3000,
    "serviceType": "",
    "serviceDescription": "",
    "redis": // redis config here
    }
};
hydraExpress.init(hydraSettings, () => {
    const api = require('express').Router();
    api.get('/test', (req, res) => {
        res.sendStatus(200);
    });

    hydraExpress.registerRoutes({
    '': api
    });
});

Now, if I go to http://localhost:3000/test - I get a response saying OK - so far, so good - it's all working fine.

// Emailer service

const hydraSettings = {
    "hydra": {
    "serviceName": "emailer",
    "serviceIP": "",
    "servicePort": 3001,
    "serviceType": "",
    "serviceDescription": "",
    "redis": // redis config here
    }
};
hydraExpress.init(hydraSettings, () => {
    const api = require('express').Router();
    api.get('/emailer-test', (req, res) => {
        res.sendStatus(200);
    });

    hydraExpress.registerRoutes({
    '': api
    });
});

If I go to http://localhost:3001/emailer-test, I get an OK result once again - as expected.

However, I do not want to directly access the emailer service from http://localhost:3001. Instead, I want the API Gateway to redirect to it when a specific path is called in the gateway. For example:

// API Gateway service

const hydraSettings = {
    "hydra": {
    "serviceName": "gateway",
    "serviceIP": "",
    "servicePort": 3000,
    "serviceType": "",
    "serviceDescription": "",
    "redis": // redis config here
    }
};
hydraExpress.init(hydraSettings, () => {
    const api = require('express').Router();
    api.get('/test', (req, res) => {
        res.sendStatus(200);
    });

    hydraExpress.registerRoutes({
    '': api,
        '/emailer/*': * delegate to emailer service, which is listening on port 3001 * 
    });
});

I am sorry if I am completely missing something obvious. Thanks for your time @cjus

cjus commented 7 years ago

In https://github.com/cjus/hello-service/blob/master/hello-service.js#L16 Note that the hello service registers /v1/hello as the route base. In your case that would be v1/emailer. We then route traffic through the hydra-router (API/Message gateway) in this way:

http://localhost:5353/v1/hello

Are you saying that you don't want to use hydra-router and instead create your own routing gateway?

zerefel commented 7 years ago

@cjus Well, this is embarrassing. I had a wrong assumption that the hydra-router module was a part of the hydra-express module and should therefore work out of the box when only using hydra-express. It all makes sense now.

Yes, I want to build my own routing gateway, as I'm planning to handle authentication in the API gateway and then authorization in each service independently. I looked into the hydra-router implementation and I guess I'll reuse a part of it to build my gateway.

On a side note, have you considered making hydra-router available on npm? The Docker images available at https://hub.docker.com/r/flywheelsports/hydra-router/tags/ have a redis dependency and have to be made configurable either through the help of environment variables or Docker links.

P.S. Thanks for inviting me to Slack :)

zerefel commented 7 years ago

I am closing this 'issue' because I managed to wrap my head around the concept. I was using stateful sessions for authentication and that's why I needed a custom gateway -- to do a DB call and populate the user object, which was then sent to all other microservices with requests. Not optimal and probably stupid, I know. However, I decided to move to JWT for authentication and replaced my own custom gateway with the hydra-router. Now it's working flawlessly and it's much easier too.

Thanks for your time and cooperation.

cjus commented 7 years ago

HydraRouter had a compatible auth service see: https://github.com/cjus/auth-svcs

Sent from my iPhone

On Aug 21, 2017, at 9:32 AM, Dimitar Todorov notifications@github.com<mailto:notifications@github.com> wrote:

Closed #124https://github.com/flywheelsports/hydra-router/issues/124.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/flywheelsports/hydra-router/issues/124#event-1214155800, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAXoOag-hd40wFHV6QxP0nqCCtp2HMWXks5saYb1gaJpZM4OkbmF.