I have a server in Node.js + Express, that exposes some APIs both to public and admins. Actually I have 2 cloned instances running, one for Test, one for Production. They are twins, exposing same routes (/admin
, /public
), but are connected to two different DataBases, and are deployed on two different addresses.
I want to use Express-Gateway to provide APIs to 3d parties, so I'll give them firstly access to the Test Server. Once it's all done, I'll give them also the Production access.
To do this, my Idea is to create just 1 eg user
, with multiple eg application
. Each eg application
will have eg credentials
to access to Server or Production.
http://server_test.com
|-------------| |-------------|
| App Prod | | Server Test |
+----► | scopes: |------+ +-----► | /public |
| | [api_prod] | | | | /admin |
| |-------------| ▼ | |-------------|
| http://gateway.com
|------| |------------|
| User | | Express |
|------| | Gateway |
| |-------------| |------------|
| | App Test | ▲ | http://server_prod.com
+----► | scopes: | | | |-------------|
| [api_test] |------+ +-----► | Server Prod |
|-------------| | /public |
| /admin |
|-------------|
According to the credentials provided, the Gateway should redirect requests to server_test.com
or server_prod.com
. My idea was to use eg scopes
to address requests to the right endpoint. So Server Test policy, will require the scope api_test
, while Server Prod will require api_prod
scope.
Anyway this solution doesn't work, because if the first match in apiEndpoints
fails, it just results in "Not Found".
Example: I make a request to http://gateway.com/public
using App Prod credentials, with api_prod
scope. It should be passed to http://server_prod.com/public
, but instead It matches first paths: '/*'
of testEndpoint
, and fails the scopes condition. So it just fails, while the correct apiEndpoint should be prodEndpoint
.
How can I solve this problem?
This is my gateway.config.yml
apiEndpoints:
testEndpoint
host:*
paths: '/*' # <--- match this
scopes: ["api_test"] # <--- but fails this
prodEndpoint
host:*
paths: '/*'
scopes: ["api_prod"] # <---- this is right
serviceEndpoints
testService
url: "http://server_test.com"
prodService
url: "http://server_prod.com"
policies
- proxy
pipelines
testEndpoint: # Test
apiEndpoints:
- testEndpoint
policies:
- proxy
- action
serviceEndpoint: testService
prodEndpoint: # Prod
apiEndpoints:
- prodEndpoint
policies:
- proxy
- action
serviceEndpoint: prodService
I solved in this way: using -rewrite
policy.
/test
or /prod
path
the correct apiEndpoint http://server_test.com
|-------------| |-------------|
| App Prod | /prod/admin /admin | Server Test |
| scopes: |-------------+ +--------► | /public |
| [api_prod] | | | | /admin |
|-------------| ▼ | |-------------|
http://gateway.com
|------------|
| Express |
| Gateway |
|-------------| |------------|
| App Test | ▲ | http://server_prod.com
| scopes: | | | |-------------|
| [api_test] |-------------+ +---------► | Server Prod |
|-------------| /test/admin /admin | /public |
| /admin |
|-------------|
This is my config file:
apiEndpoints:
testEndpoint
host:*
paths: '/test/*'
scopes: ["api_test"]
prodEndpoint
host:*
paths: '/prod/*'
scopes: ["api_prod"]
serviceEndpoints
testService
url: "http://server_test.com"
prodService
url: "http://server_prod.com"
policies
- proxy
pipelines
testEndpoint: # Test
apiEndpoints:
- testEndpoint
policies:
- rewrite: # rewrite - delete '/test'
-
condition:
name: regexpmatch
match: ^/test/?(.*)$
action:
rewrite: /$1
- proxy
- action
serviceEndpoint: testService
prodEndpoint: # Prod
apiEndpoints:
- prodEndpoint
policies:
- rewrite: # rewrite - delete '/prod'
-
condition:
name: regexpmatch
match: ^/prod/?(.*)$
action:
rewrite: /$1
- proxy
- action
serviceEndpoint: prodService