1
 
 
Profil
In deinem persönlichen Profilbereich kannst du den Status deiner Bewerbung einsehen, unvollständige Bewerbungen zwischenspeichern und aktuelle News und Events einsehen
21. September 2020

AWS Lambda mit Micronaut

Worum geht es in dem Artikel?

In diesem Artikel sehen wir uns eine Möglichkeit an, ein Java AWS Lambda mit dem noch recht neuen Microframework Micronaut zu schreiben und unseren Code mit Hilfe von Serverless in die Produktion zu bringen.

Wenn du das liest, bist du wahrscheinlich bereits mit AWS Lambda vertraut, einem AWS-Produkt, das es Entwicklern ermöglicht, kleine Anwendungen auszuführen, ohne sich um die Infrastruktur kümmern zu müssen, die sie stützt. Man muss nur ein Stück Code zu AWS hochladen und das Programm wird aufgerufen. Dann kümmert sich AWS darum, herauszufinden, wo und wie es ausgeführt werden soll (bei Bedarf).

In diesem Artikel sehen wir uns eine Möglichkeit an, ein Java-AWS-Lambda mit dem noch recht neuen Mikro-Framework Micronaut zu schreiben, und wir werden unseren Code mit Hilfe von Serverless in die Produktion überführen.

Das zu lösende Problem

In diesem Beispiel möchten wir einen AWS Lambda schreiben, der einen REST-Endpunkt namens /capital/{country} implementiert. Dieser Endpunkt nutzt die REST-Länder-API und antwortet uns mit der Hauptstadt eines bestimmten Landes. Schließlich verwenden wir ein AWS API Gateway, um unser Lambda wie folgt aufzurufen:

Response:

{
      "capital”: “<capital>”
}

Request:

 curl <api-gateway-url>/capital/{country}

The solution

Wir bauen eine klassische Klassenstruktur auf, die mit einem Controller beginnt, der einen Service aufruft, und dieser Service ruft dann einen Client auf:

test
test

Eine Controller-Klasse ist immer mit @Controller annotiert und hat einen Pfad als Parameter. In ähnlicher Weise ist unser öffentlicher Endpunkt mit @Get annotiert:

@Controller("/")
public class CapitalController {
   @Inject
   public RestCountriesService restCountriesService;
   @Get("/capital/{country}")
   public String getCapital(@PathVariable @NotBlank String country) {
     return "{\"capital\": \"" + 
restCountriesService.getCapital(country) + "\"}";
   }
}

As you can see, this controller injects a service, which is typically annotated with @Prototype:

@Prototype
public class RestCountriesService {

  @Inject
  public RestCountriesClient restCountriesClient;

  public String getCapital(String country) {
    returnOptional.ofNullable
     (restCountriesClient.fetchCountry(country))
       .flatMap(restCountriesResponses -> 
restCountriesResponses.stream().findFirst())
       .map(RestCountriesResponse::getCapital)
       .orElseThrow(() -> new HttpStatusException(NOT_FOUND,
         "Couldn't find country " + country));
  }
}

@Prototype weist Micronaut an, an jedem Injektionspunkt eine neue Instanz der annotierten Klasse zu erstellen. Dies ist äquivalent zu @Component in Spring Boot.

Im einen HTTP-Aufruf auszuführen, bietet Micronaut eine Funktion namens "deklarativer Client", die aus einer Schnittstelle besteht, die einen bestimmten Endpunkt aufruft und die Antwort mit Hilfe von Jackson auf ein DTO abbildet:

@Client("${restCountries.apiUrl}")
interface RestCountriesClient  {



      @Get("/name/{country}")
      List<RestCountriesResponse> fetchCountry(@PathVariable String 
country);
}

Diese Schnittstelle muss mit @Client und der Basis-URL des Endpunkts, den wir aufrufen wollen, annotiert werden. In diesem Fall haben wir diese URL in einer application.yml-Datei definiert, so wie man es in Spring Boot tun würde:

restCountries:
  apiUrl: https://restcountries.eu/rest/v2

Dann muss für jeden Endpunkt eine Methode definiert werden, die mit der gewünschten HTTP-Methode und optional einem Pfad versehen ist, der an die zuvor in @Client definierte Basis-URL angehängt wird. Zusätzliche Parameter wie Header oder Abfrageparameter müssen der Methode übergeben werden.

Die vollständige Liste der möglichen Parameter findest du hier: https://docs.micronaut.io/latest/guide/index.html#binding

Nach dem Aufruf von fetchCountry() wird die Klasse RestCountriesResponse bereits mit den Werten aus dem Antwortkörper der Anfrage initialisiert.

Deployment

Da wir unseren Dienst mit Serverless bereitstellen wollen, müssen wir ihn zunächst mit npm installieren:

   npm install

Dann stellen wir den Service mit diesem Skript bereit: deploy.sh

Damit wird der Gradle-Build ausgeführt und der Dienst in AWS bereitgestellt. Als Ergebnis können wir unseren Endpunkt von überall im Internet aufrufen.

Learnings

Bei der Arbeit mit Micronaut haben wir festgestellt, dass es einfach zu erlernen ist, insbesondere wenn man bereits Erfahrung mit anderen Frameworks wie Spring Boot hat, und dass es gut dokumentiert ist, mit vielen Beispielen und Anleitungen.

Obwohl wir in diesem Artikel nicht darüber gesprochen haben, haben wir auch GraalVM verwendet, eine vielversprechende Lösung, um Lambda Kaltstarts zu reduzieren.Es handelt sich jedoch um eine recht komplexe Lösung, die sicherlich nicht einfach einzurichten ist, insbesondere wenn Bibliotheken von Drittanbietern benötigt werden.

Die gesamte Anwendung mitsamt Tests ist auf GitHub unter dem unten stehenden Link verfügbar.

Ressourcen

1 Person gefällt das

0Noch keine Kommentare

Dein Kommentar
Antwort auf:  Direkt auf das Thema antworten

Ähnliche Beiträge

We want to improve out content with your feedback.

How interesting is this blogpost?

We have received your feedback.

Cookies erlauben?

OTTO und drei Partner brauchen deine Einwilligung (Klick auf "OK") bei einzelnen Datennutzungen, um Informationen auf einem Gerät zu speichern und/oder abzurufen (IP-Adresse, Nutzer-ID, Browser-Informationen).
Die Datennutzung erfolgt für personalisierte Anzeigen und Inhalte, Anzeigen- und Inhaltsmessungen sowie um Erkenntnisse über Zielgruppen und Produktentwicklungen zu gewinnen. Mehr Infos zur Einwilligung gibt’s jederzeit hier. Mit Klick auf den Link "Cookies ablehnen" kannst du deine Einwilligung jederzeit ablehnen.

Datennutzungen

OTTO arbeitet mit Partnern zusammen, die von deinem Endgerät abgerufene Daten (Trackingdaten) auch zu eigenen Zwecken (z.B. Profilbildungen) / zu Zwecken Dritter verarbeiten. Vor diesem Hintergrund erfordert nicht nur die Erhebung der Trackingdaten, sondern auch deren Weiterverarbeitung durch diese Anbieter einer Einwilligung. Die Trackingdaten werden erst dann erhoben, wenn du auf den in dem Banner auf otto.de wiedergebenden Button „OK” klickst. Bei den Partnern handelt es sich um die folgenden Unternehmen:
Google Inc., Meta Platforms Ireland Limited, elbwalker GmbH
Weitere Informationen zu den Datenverarbeitungen durch diese Partner findest du in der Datenschutzerklärung auf otto.de/jobs. Die Informationen sind außerdem über einen Link in dem Banner abrufbar.