Follow
-
Option 1: Running docker comamnds https://getkong.org/install/docker/
-
Option 2: Using docker-compose https://github.com/Kong/docker-kong/tree/master/compose
Note: issues with running curl: https://github.com/Kong/docker-kong/issues/151 Fork with fix: [email protected]:claritee/docker-kong.git
Test:
curl -i http://localhost:8001
curl -i http://localhost:8000
https://getkong.org/docs/0.13.x/getting-started/quickstart/
https://getkong.org/docs/0.13.x/admin-api
Plugins
- Rate Limiting https://getkong.org/plugins/rate-limiting/
- Admin Plugin https://getkong.org/docs/0.13.x/admin-api/#add-plugin
- Transformation Plugin https://getkong.org/plugins/request-transformer/ (REST -> GraphQL)
Add Service:
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=postcodes' \
--data 'url=http://api.postcodes.io/postcodes/'
Add Route for the Service:
curl -i -X POST \
--url http://localhost:8001/services/postcodes/routes \
--data 'hosts[]=xyz.com'
Add a Consumer:
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=xyz"
Add credentials:
curl -i -X POST \
--url http://localhost:8001/consumers/xyz/key-auth/ \
--data 'key=xyz-key'
Request:
curl -i -X GET \
--url http://localhost:8000/tw91ep \
--header 'Host: xyz.com' \
--header "apikey: xyz-key"
Or
curl http://localhost:8000/tw91ep --header 'Host: xyz.com' --header "apikey: xyz-key" | python -m json.tool
Response:
{
"status": 200,
"result": {
"postcode": "TW9 1EP",
"quality": 1,
"eastings": 517751,
"northings": 174620,
"country": "England",
"nhs_ha": "London",
"longitude": -0.30654207062725,
"latitude": 51.4583205720251,
"european_electoral_region": "London",
"primary_care_trust": "Richmond and Twickenham",
"region": "London",
"lsoa": "Richmond upon Thames 008B",
"msoa": "Richmond upon Thames 008",
"incode": "1EP",
"outcode": "TW9",
"parliamentary_constituency": "Richmond Park",
"admin_district": "Richmond upon Thames",
"parish": "Richmond upon Thames, unparished area",
"admin_county": null,
"admin_ward": "South Richmond",
"ccg": "NHS Richmond",
"nuts": "Hounslow and Richmond upon Thames",
"codes": {
"admin_district": "E09000027",
"admin_county": "E99999999",
"admin_ward": "E05000528",
"parish": "E43000217",
"parliamentary_constituency": "E14000896",
"ccg": "E38000140",
"nuts": "UKI75"
}
}
}
Example: digitransit
http://api.digitransit.fi/routing/v1/routers/finland/index/graphql
Add Service:
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=digitransit' \
--data 'url=http://api.digitransit.fi/routing/v1/routers/finland/index/graphql'
Add Route:
curl -i -X POST \
--url http://localhost:8001/services/digitransit/routes \
--data 'hosts[]=xxx.com'
Consumer:
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=digitransit"
Add credentials:
curl -i -X POST \
--url http://localhost:8001/consumers/digitransit/key-auth/ \
--data 'key=digitransit-key'
TEST request:
curl -i -L 'http://localhost:8000' \
-H 'Host: xxx.com' \
-H "apikey: digitransit-key" \
-H 'Content-Type: application/json' \
--data-binary '{"query":"{\n agencies {\n id\n fareUrl\n }\n}","variables":null}' --compressed
Based from
curl 'http://api.digitransit.fi/routing/v1/routers/finland/index/graphql' \
-H 'Content-Type: application/json' \
--data-binary '{"query":"{\n agencies {\n id\n fareUrl\n }\n}","variables":null}' --compressed
Cluster leader issue Kong/docker-kong#85
nginx-lb_1 | time="xxx" level=warning msg="Failed to query kong-8000: Unexpected response code: 500 (No cluster leader) [<nil>]"
consul_1 | xxx [ERR] http: Request /v1/health/service/kong-8001?passing=1, error: No cluster leader
consul_1 | xxx [ERR] http: Request /v1/health/service/kong-8444?passing=1, error: No cluster leader
nginx-lb_1 | time="xxx" level=warning msg="Failed to query kong-8443: Unexpected response code: 500 (No cluster leader) [<nil>]"
nginx-lb_1 | time="xxx" level=warning msg="Failed to query kong-8001: Unexpected response code: 500 (No cluster leader) [<nil>]"
nginx-lb_1 | time="xxx" level=warning msg="Failed to query kong-8444: Unexpected response code: 500 (No cluster leader) [<nil>]"
nginx-lb_1 | 127.0.0.1 - - xxx] "GET /health HTTP/1.1" 200 100 "-" "curl/7.52.1"
consul_1 | 2018/04/25 08:50:18 [ERR] agent: failed to sync changes: No cluster leader
Workaround:
docker-compose stop consul; docker-compose rm -f consul; docker-compose up -d consul
docker-compose up -d
Afterwards start consul first, then the rest of the services, i.e.
docker-compose up -d consul
docker-compose up -d
About Kong
Docker
Libraries
Restricting Access and Rate Limiting
Tutorials
- http://www.tothenew.com/blog/getting-started-with-application-authentication-via-kong-api-gateway/
- Using docker compose https://blog.toast38coza.me/up-and-running-with-kong-and-docker/
Kong and GraphQL
- https://stackoverflow.com/questions/44416904/use-kong-as-api-gateway-to-graphql-rest-services
- https://medium.com/statuscode/integrating-openfaas-and-graphql-experimental-1870bd22f2a
GraphQL as a Gateway?
-
https://blog.graph.cool/graphql-api-gateway-graphql-native-1e46e4f179f7
-
https://blog.codeship.com/graphql-as-an-api-gateway-to-micro-services/
Most of the disadvantages to this approach have to do with GraphQL in general. The biggest problem with GraphQL when it comes to filling the role of an API gateway is the fact that it operates on a single endpoint. API gateways often define authorization rules, throttling rates, and caching times differently for each route. But since GraphQL uses only one endpoint, it’s nearly impossible to define route-specific rules for anything. Consequently, you may need to write authorization, throttling, and caching logic in a separate layer or perhaps even in your microservices themselves. This can create its own mess of smelly code because the solutions will end up undercutting some of the most basic functionality that we expect from the gateway.
Alternatives
- AWS API Gateway and Apollo - https://medium.com/merapar/apollo-client-with-aws-api-gw-9fd25ce9f72d
- AWS API Gateway - https://aws.amazon.com/api-gateway/