how to rename endpoints with express gateway? - express-gateway

i am trying to build an api that consists of different services and i want to everything to start with /api/ path. like the following below.
i want https://thirdparthy/comments to be routed as /api/comments on express gateway. what is the correct confirmation?
http:
port: 4000
admin:
port: 9876
hostname: localhost
apiEndpoints:
users:
host: localhost
paths: '/api/users'
comments:
host: localhost
paths: '/api/comments'
serviceEndpoints:
users:
url: 'https://jsonplaceholder.typicode.com/users'
comments:
url: 'https://jsonplaceholder.typicode.com/comments'
policies:
- basic-auth
- cors
- expression
- key-auth
- log
- oauth2
- proxy
- rate-limit
pipelines:
users:
apiEndpoints:
- users
policies:
- proxy:
- action:
serviceEndpoint: users
prependPath: false
ignorePath: false
comments:
apiEndpoints:
- comments
policies:
- proxy:
- action:
serviceEndpoint: comments
prependPath: false
ignorePath: false

you can either use the rewrite policy to change the target url or simply configure the proxy policy accordingly:
- proxy:
- action:
serviceEndpoint: comments
prependPath: true
ignorePath: false
This should do the job.
Cheers,
V.

Related

How to deploy grpc-web on aws?

I have a backend service that I want to expose via grpc-web.
I'm able to use the service directly via the public IP of the ec2 instance. But when I try to access it via the invocation URL of API Gateway I get a CORS error.
I want to add JWT authentication that's why I want to expose the API via API-Gateway.
Here is my configuration:
Envoy.yml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: listener_sim
address:
socket_address: { address: 0.0.0.0, port_value: 8080 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
codec_type: auto
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route:
cluster: rtdxc_service
timeout: 0s
max_stream_duration:
grpc_timeout_header_max: 0s
cors:
allow_origin_string_match:
- prefix: "*"
allow_methods: GET, PUT, DELETE, POST, OPTIONS
allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
max_age: "1728000"
expose_headers: grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
"#type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: grpc_server
connect_timeout: 0.25s
type: logical_dns
http2_protocol_options: {}
lb_policy: round_robin
load_assignment:
cluster_name: rtdxc_0
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpc_server
port_value: 8081
Here is my docker-compose.yml
version: '3.8'
services:
grpc_server:
image: XXXXXX
user: ${UID}:${GID}
ports:
- 8081:8081
tty: true
proxy:
ports:
- 9091:9091
- 8080:8080
image: envoyproxy/envoy:v1.22.0
volumes:
- ./envoy/envoy.yml:/etc/envoy/envoy.yaml:ro
tty:
true
I have mapped API gateway with the following configuration:
ANY / mappes to the public domain of the ec2 instance on port 8080
If I add CORS configuration in the API Gateway , The OPTION request returns 204 with propper cors headers, but POST request does not return proper headers. If I disable CORS configuration in the API gateway, the OPTIONS request also fails due to CORS issue.

serverless create_domain - Failed to create custom domain

I am trying to use serverless-domain-manager to deploy serverless to custom domains on AWS but every time I run serverless create_domain I get the generic error "Failed to create custom domain". Here are the steps I've taken and the contents of my yml:
Registered domain on AWS
Set up a hosted zone in route 53
Created a certificate for *.mydomain.com in certificate manager in AWS
Created an iAM user with admin privileges
Run aws configure with iAM user keys
.yml
service: service-name
plugins:
- serverless-apigw-binary
- serverless-apigwy-binary
- serverless-content-encoding
- serverless-api-cloudfront
- serverless-plugin-tracing
- serverless-domain-manager
custom:
apigwBinary:
types:
- 'image/jpeg'
- 'text/html'
- 'text/css'
- 'application/javascript'
- 'application/x-javascript'
- '*/*'
contentEncoding:
minimumCompressionSize: 0
stage: ${opt:stage, self:provider.stage}
domains:
prod: api.mydomain.com
test: api-test.mydomain.com
dev: api-dev.mydomain.com
customDomain:
basePath: ""
domainName: ${self:custom.domains.${self:custom.stage}}
stage: "${self:custom.stage}"
createRoute53Record: true
certificateArn: "cert-arn"
hostedZoneId: "zone-id"
provider:
name: aws
runtime: nodejs12.x
endpointType: regional
region: ap-southeast-2
memorySize: 3008
timeout: 300
tracing: true
iamRoleStatements:
- Effect: 'Allow'
Action:
- 'xray:PutTraceSegments'
- 'xray:PutTelemetryRecords'
- 'lambda:InvokeFunction'
Resource:
- '*'
package:
exclude:
- node_modules/aws-sdk/**
- .vscode/**
- bin/**
- obj/**
functions:
api:
warmup: true
handler: index.handler
events:
- http: ANY /
- http: 'ANY {proxy+}'
Every time I run serverless create_domain I get the same generic error with no extra info.
Thanks
As Erico pointed out you get a bit more info with SLS_DEBUG. It could be that you have an issue with domain certificate and that debug message would tell you that.
In my case it seemed to be a cert problem as it was in a different AWS region so sls create_domain couldn't find it. Overall it's been a rather confusing experience.
Check out the endpointType option:
customDomain:
...
endpointType="regional"
https://github.com/amplify-education/serverless-domain-manager/issues/46
https://aws.amazon.com/about-aws/whats-new/2017/11/amazon-api-gateway-supports-regional-api-endpoints/
In my case, my hosted zone is in another AWS account, so createRoute53Record: true failed to create the route53 record and the hence the generic error.
Changing to createRoute53Record: false fixed the error for me.

Need redirect my gateway to a enpoint (bad request)

well I need create a endpoint where can create a user, using express-gateway, in this have 2 ports running.
gateway http server listening on :::8181
admin http server listening on 127.0.0.1:9876
I can create a user sending my information to:
http://127.0.0.1:9876/users
I can't use this how my end point because have other configuration on my frontend, so in my frontend send my information for create user to:
http://localhost:8181/api/user/create
Now I need send my information to this http://localhost:8181/api/user/create and redirect internal in the gateway to this http://127.0.0.1:9876/users, I try something but just have bad gateway or not found. I call this end point users, so this is the script.
http:
port: 8181
admin:
port: 9876
host: localhost
apiEndpoints:
events:
host: localhost
paths: ["/api/events*", "/swagger*"]
methods: ["GET", "PATCH"]
users:
host: localhost
paths: "/api/user/create*"
url: "http://localhost:9876"
methods: ["POST", "OPTIONS"]
eventsCreate:
host: localhost
paths: "/api/events*"
methods: ["POST", "PUT", "OPTIONS"]
auth:
host: localhost
paths: "/api/auth*"
methods: ["POST", "GET", "OPTIONS"]
serviceEndpoints:
auth:
url: "http://localhost:59868"
events:
url: "http://localhost:5000"
users:
url: "http://localhost:9876"
policies:
- basic-auth
- cors
- expression
- key-auth
- log
- oauth2
- proxy
- rate-limit
- jwt
- request-transformer
pipelines:
authPipeline:
apiEndpoints:
- auth
policies:
- cors:
- log:
action:
message: "auth ${req.method}"
- proxy:
action:
serviceEndpoint: auth
changeOrigin: true
eventsPipeline:
apiEndpoints:
- events
policies:
- cors:
- log:
action:
message: "events ${req.method}"
- proxy:
action:
serviceEndpoint: events
changeOrigin: true
usersPipeline:
apiEndpoints:
- users
policies:
- cors:
- log:
action:
message: "users ${req.method}"
- proxy:
action:
serviceEndpoint: users
changeOrigin: true
userPipeline:
apiEndpoints:
- events
policies:
- cors:
- log:
action:
message: "events ${req.method}"
- proxy:
action:
serviceEndpoint: events
changeOrigin: true
eventsCreatePipeline:
apiEndpoints:
- eventsCreate
policies:
- cors:
- log:
action:
message: "events ${req.method}"
- jwt:
action:
secretOrPublicKey: "MORTADELAIsMyPassion321"
checkCredentialExistence: false
- proxy:
action:
serviceEndpoint: events
changeOrigin: true
You are trying to map the incoming URL http://localhost:8181/api/user/create to the Express Gateway administration URL http://localhost:9876/users, but your proxy policy only changes the hostname and port components of the URL, not the path.
This is described in the Path Management section of the Proxy documentation.
To change the path, you'll need to either adjust the existing users service endpoint or create a new one, and add some instructions to the proxy middleware configuration:
For example, add a new ServiceEndpoint called userCreate:
serviceEndpoints:
auth:
url: "http://localhost:59868"
userCreate:
url: "http://localhost:9876/users"
users:
url: "http://localhost:9876"
And then refer to the new service endpoint and set stripPath in the proxy configuration:
- proxy:
action:
serviceEndpoint: userCreate
changeOrigin: true
stripPath: true

how to use scopes in Oauth2.0 to authorize user using Express Gateway(Microservice API Gateway)?

I did scopes with key-auth mechanism is perfectly working, but when i use scopes with Oauth2.0 mechanism, i am getting unauthorized error.
I did without scopes, the Oauth2.0 mechanism is working perfectly. Please suggest how to solve this problem?
Following is Gateway YAML configuration:
http:
port: 8080
admin:
port: 9876
host: localhost
apiEndpoints:
api:
- host: 'localhost'
paths: ['/user', '/user/:id']
methods: ["GET"]
scopes: ["user"]
- host: 'localhost'
paths: ['/user', '/user/:id']
methods: ["PUT", "POST", "DELETE"]
scopes: ["admin"]
myApiRest:
host: 'localhost'
paths: '/posts'
serviceEndpoints:
jsonplaceholder:
url: 'http://localhost:8899'
restDummyService:
url: 'https://jsonplaceholder.typicode.com'
policies:
- basic-auth
- cors
- expression
- key-auth
- log
- oauth2
- proxy
- rate-limit
pipelines:
- name: one
apiEndpoints:
- api
policies:
- oauth2:
#- basic-auth:
#- key-auth:
- proxy:
- action:
serviceEndpoint: jsonplaceholder
changeOrigin: true
- name: two
apiEndpoints:
- myApiRest
policies:
#- key-auth:
- proxy:
- action:
serviceEndpoint: restDummyService
changeOrigin: true

Serverless custom domain

I want to setup a custom domain with the serverless framework and AWS.
This is what I have in serverless.yml
service: chapiLabs-rest-api
plugins:
- serverless-domain-manager
- serverless-express
custom:
customDomain:
domainName: chapitime.chapilabs.com
basePath: ''
stage: ${self:provider.stage}
certificateName: '*.chapilabs.com'
createRoute53Record: true
package:
exclude:
- node_modules
include:
- dist
provider:
name: aws
runtime: nodejs8.10
webpackIncludeModules:
forceInclude:
- mysql
- mysql2
- sequelize
functions:
get:
handler: dist/get.get
events:
- http:
path: v1/client/{id}
method: get
request:
parameters:
paths:
id: true
create:
handler: dist/auth.auth
events:
- http:
path: v1/auth
method: post
I used this npm package as plugin: https://github.com/amplify-education/serverless-domain-manager
I added a certificate via DNS using CloudFlare
Then I made a deploy and got the next log.
In cloudflare I added a CNAME to add the ACM validation and another CNAME pointing cloudfront.
But the domain name is not working. Any ideas why? I didn't bought the domain in AWS.
After some deployments the cloudfront url changed and I didn't noticed. I just updated the CNAME record in CloudFlare and it started working.