===== API Gateway =====
Real-time applications with API Gateway WebSockets and AWS Lambda
https://serverless.com/blog/api-gateway-websockets-support/
Calling API gateways via generated SDKs
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-generate-sdk-javascript.html
===== REST API vs HTTP API =====
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html
REST-Api has more functionality regarding inspection.
===== Lambda behind the API gateway =====
https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax
==== Fallpit: Invoke Lambda POST ====
The API must invoke the backend Lambda function using the **HTTP method POST**.
https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html#API_Invoke_RequestSyntax
Otherwise you will get
* a 500 error on the Gateway
* a 403 error on the Lambda, behind the Gateway https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-lambda-template-invoke-error/
==== Debugging ====
If a Lambda does not behave as intended - use the **Test button**.
ONe can see much more exceptions in there.
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/gDyYDmOwNf.png}}
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/0SwqtTPgvP.png}}
==== Java Lambda behind the API gateway ====
https://www.baeldung.com/aws-lambda-api-gateway
Example: https://github.com/skipidar/aws-javalambda-behind-apigateway
=== Java signature ===
There are obligations on the Java-Lambda signature, when executed behind Gateway.
It is important to have
* InputStream inputStream,
* OutputStream outputStream
in the interface of the Lambda - otherwise the API Gateway will throw exceptions
Dependencies
dependencies {
implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
implementation 'com.google.code.gson:gson:2.8.6'
testImplementation 'org.apache.logging.log4j:log4j-api:2.13.0'
testImplementation 'org.apache.logging.log4j:log4j-core:2.13.0'
testImplementation 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0'
compile 'com.googlecode.json-simple:json-simple:1.1.1'
}
package example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.nimbusds.oauth2.sdk.TokenRequest;
import no.nav.security.mock.oauth2.MockOAuth2Server;
import no.nav.security.mock.oauth2.token.OAuth2TokenCallback;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
// Handler value: example.Handler
public class Handler implements RequestStreamHandler {
/**
* The handleRequest interface, as below,
* with InputStream, OutputStream
*
* when Lambda is used with the API Gateway - is required.
*
* https://www.baeldung.com/aws-lambda-api-gateway
*
* @param inputStream
* @param outputStream
* @param context
* @throws IOException
*/
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
JSONParser parser = new JSONParser();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
JSONObject responseJson = new JSONObject();
JSONObject event = null;
try {
event = (JSONObject) parser.parse(reader);
handleEvent(event,
responseJson,
inputStream,
outputStream,
context);
} catch (ParseException e) {
responseJson.put("statusCode", 400);
responseJson.put("exception", e);
}
// example response
JSONObject obj2 = new JSONObject();
obj2.put("Content-Type", "application/json");
responseJson.put("statusCode", 200);
responseJson.put("headers", obj2);
responseJson.put("body", "hello world");
// writing the result into the
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write(responseJson.toString());
writer.close();
}
=== Return format of Lambda ===
Lambdas needs to return JSON, to be capable to be used from the gateway.
https://docs.amazonaws.cn/en_us/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format
// Handler value: example.Handler
public class Handler implements RequestStreamHandler {
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
// example response
JSONObject obj2 = new JSONObject();
obj2.put("Content-Type", "application/json");
responseJson.put("statusCode", 200);
responseJson.put("headers", obj2);
responseJson.put("body", "hello world");
// writing the result into the
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");
writer.write(responseJson.toString());
writer.close();
==== Use Lambda Proxy integration ====
When a client submits an API request, API Gateway passes to the integrated Lambda function the raw request as-is:
That means, that the option `Use Lambda Proxy integration`
* **deactivates** the **"Mapping Templates"**
* https://aws.amazon.com/premiumsupport/knowledge-center/custom-headers-api-gateway-lambda/
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/vC2XDM5VDx.png}}
This is the most powerful integration:
- **\{{proxy}}** sends all resources - to the Lambda
- **ANY** - accepts all methods
https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-proxy-resource%3Ficmpid=docs_apigateway_console
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/M51LDfQis7.png}}
* Still the API must be deployed to a "stage"
* Minimum one resource must be present after the stage - or you will get "{"message":"Missing Authentication Token"}"
After that the lambda reacts on
curl -X POST https://s5oi8r61hk.execute-api.eu-west-1.amazonaws.com/stage/someresourcehere/1/2/bla/blub/enigma21/
curl -X GET https://s5oi8r61hk.execute-api.eu-west-1.amazonaws.com/stage/2/
==== Mapping Templates ====
Can be used to add custom headers
from the API gateway
to the Lambda
https://aws.amazon.com/premiumsupport/knowledge-center/custom-headers-api-gateway-lambda/
==== Token Exchange =====
The token exchange is possible with 2 pieces:
* obtain a new token at the lambda authorizer
* set the header via VLT as in
https://stackoverflow.com/questions/40585016/is-it-possible-to-add-an-http-header-from-aws-custom-auth-on-api-gateway
===== A Detailed Overview of AWS API Gateway =====
An overview of the API gateway functions.
https://www.alexdebrie.com/posts/api-gateway-elements/
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/44ovAxhCbW.png}}
{{https://s3.eu-central-1.amazonaws.com/alf-digital-wiki-pics/sharex/QuF6kGfybF.png}}