Inzicht

Lorenz vanthillo

6 min. read

Hoe REST API’s integreren met EventBridge? Een demo-setup om u op weg te helpen.

AWS EventBridge is een serverloze event bus-service die het eenvoudig maakt om events van verschillende AWS-services en aangepaste bronnen op te nemen, te filteren en te routeren. Het stelt u in staat om event-gedreven applicaties en architecturen te bouwen. Maar hoe integreert u REST API’s met EventBridge? Laten we dat uitzoeken in een demo!

De theorie

Er zijn verschillende algemeen erkende methoden voor het verzenden van events naar een EventBridge bus:

  • AWS Service Integraties
    Events kunnen automatisch naar de EventBridge bus worden verzonden wanneer specifieke gebeurtenissen plaatsvinden binnen uw AWS-omgeving, bijvoorbeeld wanneer een server opschaalt.
  • AWS Partner Integraties
    EventBridge biedt integraties met externe partner SaaS-producten zoals Salesforce, DataDog, Zendesk en meer. Dit stelt events van deze services in staat om naadloos doorgestuurd te worden naar uw EventBridge bus.
  • Aangepaste Events
    U kunt aangepaste events creëren en publiceren naar de event bus met behulp van de EventBridge API. Dit houdt in dat u aangepaste code schrijft en de AWS SDK gebruikt om events te creëren en te publiceren volgens uw specifieke vereisten.
  • Cron-gebaseerde Events
    Events kunnen ook worden gepland en getriggerd op specifieke tijden met behulp van cron-expressies, waardoor u acties kunt automatiseren op precieze intervallen.

Een veel minder bekende, maar vaak zeer waardevolle integratie, is de directe integratie tussen API Gateway en EventBridge. Deze integratie biedt de mogelijkheid om een REST API-event te behandelen als een event-bericht door het te publiceren naar een event bus en het vervolgens te gebruiken binnen een event-gedreven workflow.

De theorie in de praktijk

In deze demo-setup zullen we een REST API creëren met een POST-methode die gebruikers in staat stelt om autogegevens naar de API te verzenden. Deze gegevens worden gevalideerd, getransformeerd en vervolgens gepubliceerd naar onze Event bus. Afhankelijk van de inhoud van de body wordt het gerouteerd naar de juiste SQS-wachtrij voor verdere verwerking.

rest api's integreren met eventbridge demo

U kunt alle code voor deze demo vinden in de dropdowns.

Een voorbeeldverzoek voor POST /carDetails
curl --location --request POST https://<ID>.execute-api.eu-west-1.amazonaws.com/prod/CarDetails --header 'Content-Type: application/json' \
--data-raw '
{
    "items":[
        {
            "CarData":"{\"data\":\"Audi A4 is created\"}",
            "BrandType":"audi",
            "Source": "car_data"
        }
    ]
}'

Om deze oplossing te implementeren, gebruiken we AWS SAM. Dit is een uitbreiding van CloudFormation, een AWS-native Infrastructure as Code (IaC) service. De uitbreiding biedt betere integratie met serverloze services zoals API Gateway en Lambda. De primaire focus van deze blog ligt niet op SAM, maar het dient als een handigere setup-methode voor mij vergeleken met “ClickOps.”

Het volledige template is beschikbaar hier en kan worden geïmplementeerd met behulp van bepaalde commando’s.

De commando’s
$ sam build
$ sam deploy --stack-name api-gw-eventbridge-demo --capabilities CAPABILITY_IAM

Laten we onze template eens nader bekijken. Het belangrijkste onderdeel is onze API-methodeconfiguratie.

De API-methodeconfiguratie
  apiGatewayRootMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      AuthorizationType: NONE
      HttpMethod: POST
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: Empty
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS
        Credentials: !GetAtt ApiGatewayRole.Arn 
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:events:action/PutEvents
        PassthroughBehavior: WHEN_NO_TEMPLATES
        RequestTemplates: 
          application/json: !Sub 
            - |- 
              #set($context.requestOverride.header.X-Amz-Target = "AWSEvents.PutEvents")
              #set($context.requestOverride.header.Content-Type = "application/x-amz-json-1.1")            
              #set($inputRoot = $input.path('$')) 
              { 
                "Entries": [
                  #foreach($elem in $inputRoot.items)
                  {
                    "Detail": "$util.escapeJavaScript($elem.CarData).replaceAll("\\'","'")",
                    "DetailType": "$elem.BrandType",
                    "Source": "$elem.Source",
                    "EventBusName": "${EventBusName}"
                  }#if($foreach.hasNext),#end
                  #end
                ]
              }
            - { EventBusName: !Ref EventBus }
        IntegrationResponses:
          ...
      ResourceId: !Ref apiGatewayResource
      RestApiId: !Ref apiGateway

Voor de integratie-URI configureren we arn:aws:apigateway:${AWS::Region}:events:action/PutEvents, waarmee we onze API Gateway POST-methode koppelen aan EventBridge. Vervolgens gebruiken we de Velocity Template Language (VTL) om een mapping template te maken. Dit template is ontworpen om onze request body te transformeren en af te stemmen op de vereiste request-structuur voor de EventBridge PutEvents API.

De vereiste structuur
{
   "Entries": [ 
      { 
         "Detail": "string",
         "DetailType": "string",
         "EventBusName": "string",
         "Resources": [ "string" ],
         "Source": "string",
         "Time": number,
         "TraceHeader": "string"
      }
   ]
}

Detail, DetailType en Source zijn vereist voor EventBridge om succesvol een event naar een event bus te verzenden.

Onze input-items (zoals te zien in het voorbeeldverzoek) worden gemapped om te voldoen aan de bovenstaande structuur. We transformeren onze lijst van items naar een lijst van entries.

De lijst van entries
{ 
   "Entries": [
      #foreach($elem in $inputRoot.items)
        {
          "Detail": "$util.escapeJavaScript($elem.CarData).replaceAll("\\'","'")",
          "DetailType": "$elem.BrandType",
          "Source": "$elem.Source",
          "EventBusName": "${EventBusName}"
        }#if($foreach.hasNext),#end
        #end
  ]
}

Dankzij de EventBusName-eigenschap zal AWS automatisch bepalen naar welke bus dit event doorgestuurd moet worden. De EventBusName wordt automatisch doorgegeven door ons SAM-template. Onze Event Bus wordt binnen datzelfde template gecreëerd en wordt gerefereerd door ons mapping template.

De API en zijn mapping template in AWS

mapping template in AWS
mapping template

Nu we de API Gateway – EventBridge integratie begrijpen, kunnen we onze EventBridge-regels controleren. EventBridge-regels zijn regels die op een bus worden gecreëerd en definiëren hoe specifieke events gerouteerd moeten worden naar bepaalde targets op basis van de inhoud van de events.

De regel die we hebben gecreëerd voor “Audi”

(We hebben een vergelijkbare regel voor “BMW”)

  AudiEventsRule:
    Type: "AWS::Events::Rule"
    Properties:
      Description: "Rule to capture Audi events and send to AudiQueue"
      EventBusName: !GetAtt EventBus.Name
      EventPattern:
        source:
          - "car_data"
        detail-type:
          - "audi"
      Targets:
        - Arn: !GetAtt AudiQueue.Arn
          Id: "AudiQueueTarget"  

Als het event “car_data” als bron heeft en detail-type overeenkomt met “audi”, wordt het doorgestuurd naar de Audi SQS-wachtrij. Een vergelijkbare regel is ingesteld voor het detail-type “bmw.” Als het niet overeenkomt met een van deze criteria, wordt het event weggegooid en nergens naartoe gerouteerd.

Om de complete setup te testen, moeten we een POST-verzoek uitvoeren naar onze API.

Het POST-verzoek naar onze API
curl --location --request POST https://<ID>.execute-api.eu-west-1.amazonaws.com/prod/CarDetails --header 'Content-Type: application/json' \
--data-raw '
{
    "items":[
        {
            "CarData":"{\"data\":\"Audi A4 is created\"}",
            "BrandType":"audi",
            "Source": "car_data"
        }
    ]
}'

Dit verzoek bevat alle attributen die nodig zijn voor ons mapping template om de juiste transformatie uit te voeren. In de logs kunnen we zowel ons oorspronkelijke als ons getransformeerde verzoek zien.

logs

De payload wordt doorgestuurd als een event naar onze Event Bus. We hebben twee regels gecreëerd op onze bus, en ons event komt overeen met een van deze regels:

  • Het heeft detail-type audi
  • Het heeft source car_data

Onze regel stuurt het event door naar onze Audi SQS-wachtrij.

Onze event bus en zijn regels

event bus en twee regels

Natuurlijk kunt u veel geavanceerdere regels creëren, en u kunt uw event ook verrijken door extra data toe te voegen met behulp van EventBridge pipes, en nog veel meer. Dit is eigenlijk slechts het begin van de werkelijk spannende event-gedreven mogelijkheden.

Laten we nu berichten ophalen uit onze Audi SQS-wachtrij. Die wachtrij is geconfigureerd als target van onze Audi EventBridge-regel. We zien dat er één bericht beschikbaar is op de audi-queue.

Poll het bericht en controleer de inhoud.

Het uiteindelijke bericht

Daar is het! De payload van ons POST-verzoek is nu een bericht dat klaar is voor gebruik in een event-gedreven workflow. AWS biedt talloze integraties met EventBridge, waardoor u Step Function-workflows kunt starten of Lambda Functions kunt gebruiken voor verdere event-verwerking.

Conclusie

In theorie

Deze setup leert ons dat het integreren van REST API’s met EventBridge eenvoudig is. We hoeven geen aangepaste code, servers of Lambda’s te schrijven of onderhouden. We kunnen de payload van een verzoek omzetten in een bericht dat geschikt is voor elke event-gedreven workflow.

In de praktijk

Dit betekent dat clients geen aangepaste code hoeven te schrijven of de AWS-specifieke SDK hoeven te gebruiken om events naar EventBridge te publiceren. Ze kunnen eenvoudig integreren met een veelgebruikt HTTP-endpoint. Ze hoeven niet bekend te zijn met de AWS-specifieke details maar kunnen toch profiteren van alle voordelen die event-gedreven flows bieden in AWS.

Geïnteresseerd in een samenwerking?