diff --git a/src/main/java/EchoServer.java b/src/main/java/de/hdm/jordine/vorlesung/clientserver/EchoServer.java
similarity index 96%
rename from src/main/java/EchoServer.java
rename to src/main/java/de/hdm/jordine/vorlesung/clientserver/EchoServer.java
index 0cd7922f2780385e4b71d798e5266cdb7d5c2c82..0191f526bde1696095e017499625e7a22e671c7f 100644
--- a/src/main/java/EchoServer.java
+++ b/src/main/java/de/hdm/jordine/vorlesung/clientserver/EchoServer.java
@@ -1,3 +1,5 @@
+package de.hdm.jordine.vorlesung.clientserver;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
diff --git a/src/main/java/GreetClient.java b/src/main/java/de/hdm/jordine/vorlesung/clientserver/GreetClient.java
similarity index 96%
rename from src/main/java/GreetClient.java
rename to src/main/java/de/hdm/jordine/vorlesung/clientserver/GreetClient.java
index f3c76cef85627fb6c7f25a88877b27e874309b2a..d9b1add4f671f1a9e2ed82bffe545330559ac4ae 100644
--- a/src/main/java/GreetClient.java
+++ b/src/main/java/de/hdm/jordine/vorlesung/clientserver/GreetClient.java
@@ -1,3 +1,5 @@
+package de.hdm.jordine.vorlesung.clientserver;
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/ConcurrentModificationDemo.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/ConcurrentModificationDemo.java
new file mode 100644
index 0000000000000000000000000000000000000000..0ed2f17bc9fd45c4b799994856c433c0a1854760
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/ConcurrentModificationDemo.java
@@ -0,0 +1,27 @@
+package de.hdm.jordine.vorlesung.concurrency.issues;
+
+import java.util.*;
+
+//based on https://www.geeksforgeeks.org/difference-traditional-collections-concurrent-collections-java/
+
+public class ConcurrentModificationDemo{
+
+    public static void main(String[] args) throws InterruptedException {
+        Collection<Integer> asyncCollection = new ArrayList<>();
+        Runnable listOperations = () -> {
+            for (int i = 0; i < 100; i++) {
+                asyncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));
+            }
+        };
+
+        Thread thread1 = new Thread(listOperations);
+        Thread thread2 = new Thread(listOperations);
+        thread1.start();
+        thread2.start();
+        thread1.join();
+        thread2.join();
+
+        System.out.println(asyncCollection.size());
+    }
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/DeadLock.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/DeadLock.java
new file mode 100644
index 0000000000000000000000000000000000000000..3eccef3df42903399fb43426a3154e60bc8034c7
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/DeadLock.java
@@ -0,0 +1,60 @@
+package de.hdm.jordine.vorlesung.concurrency.issues;
+
+// based on https://www.tutorialspoint.com/java/java_thread_deadlock.htm
+
+public class DeadLock {
+
+    public static void main(String[] args) {
+
+        Object lock1 = new Object();
+        Object lock2 = new Object();
+
+        Thread t0 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (lock1){
+                    System.out.println("Thread 1 has lock1");
+                    try {
+                        Thread.sleep(10);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+
+                    System.out.println("Thread 1 waiting for lock2");
+
+                    synchronized (lock2){
+                        System.out.println("Thread 1 has lock2 and lock1");
+                    }
+                }
+
+            }
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (lock2){
+                    System.out.println("Thread 2 has lock2");
+                    try {
+                        Thread.sleep(10);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+
+                    System.out.println("Thread 2 waiting for lock1");
+
+                    synchronized (lock1){
+                        System.out.println("Thread 2 has lock1 and lock2");
+                    }
+                }
+            }
+        });
+
+        t0.start();
+        t1.start();
+
+    }
+
+
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/LostUpdate.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/LostUpdate.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c3d45d3a5129e1c275d7c5d3f60d1bb4b8ff1c6
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/issues/LostUpdate.java
@@ -0,0 +1,43 @@
+package de.hdm.jordine.vorlesung.concurrency.issues;
+
+public class LostUpdate {
+
+    private int counter = 0;
+
+    public void increment(){
+        counter++;
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+        LostUpdate lu = new LostUpdate();
+
+        Thread t0 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        t0.start();
+        t1.start();
+
+        //t0.join();
+        //t1.join();
+
+        System.out.println("Counter value: " + lu.counter);
+    }
+
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/ConcurrentModificationSolutionDemo.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/ConcurrentModificationSolutionDemo.java
new file mode 100644
index 0000000000000000000000000000000000000000..789553b7b062474df906d6432f495ff99a0dc060
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/ConcurrentModificationSolutionDemo.java
@@ -0,0 +1,27 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+import java.util.*;
+
+//based on https://www.baeldung.com/java-synchronized-collections
+
+public class ConcurrentModificationSolutionDemo{
+
+    public static void main(String[] args) throws InterruptedException {
+        Collection<Integer> syncCollection = Collections.synchronizedCollection(new ArrayList<>());
+        Runnable listOperations = () -> {
+            for (int i = 0; i < 100; i++) {
+                syncCollection.addAll(Arrays.asList(1, 2, 3, 4, 5, 6));
+            }
+        };
+
+        Thread thread1 = new Thread(listOperations);
+        Thread thread2 = new Thread(listOperations);
+        thread1.start();
+        thread2.start();
+        thread1.join();
+        thread2.join();
+
+        System.out.println(syncCollection.size());
+    }
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/DeadLockSolution.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/DeadLockSolution.java
new file mode 100644
index 0000000000000000000000000000000000000000..72c0061d4f83a13bf4f994935606a3b19923b5a9
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/DeadLockSolution.java
@@ -0,0 +1,60 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+// based on https://www.tutorialspoint.com/java/java_thread_deadlock.htm
+
+public class DeadLockSolution {
+
+    public static void main(String[] args) {
+
+        Object lock1 = new Object();
+        Object lock2 = new Object();
+
+        Thread t0 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (lock1){
+                    System.out.println("Thread 1 has lock1");
+                    try {
+                        Thread.sleep(10);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+
+                    System.out.println("Thread 1 waiting for lock2");
+
+                    synchronized (lock2){
+                        System.out.println("Thread 1 has lock1 and lock2");
+                    }
+                }
+
+            }
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                synchronized (lock1){
+                    System.out.println("Thread 2 has lock2");
+                    try {
+                        Thread.sleep(10);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+
+                    System.out.println("Thread 2 waiting for lock1");
+
+                    synchronized (lock2){
+                        System.out.println("Thread 2 has lock1 and lock2");
+                    }
+                }
+            }
+        });
+
+        t0.start();
+        t1.start();
+
+    }
+
+
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/FutureDemo.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/FutureDemo.java
new file mode 100644
index 0000000000000000000000000000000000000000..07fd8efa33d272e117f610e40aac675b7d5eb425
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/FutureDemo.java
@@ -0,0 +1,53 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+import java.util.concurrent.*;
+
+// based on https://www.baeldung.com/java-future
+
+public class FutureDemo {
+
+    private ExecutorService executor;
+
+    public Future<Integer> calculate(Integer input) {
+        executor = Executors.newFixedThreadPool(10);
+        return executor.submit(new Callable<Integer>() {
+            @Override
+            public Integer call() throws Exception {
+                Thread.sleep(1000);
+                return input * input;
+            }
+        });
+    }
+
+    public void shutdownExecutor() throws InterruptedException {
+        executor.shutdown();
+        try {
+            if (!executor.awaitTermination(800, TimeUnit.MILLISECONDS)) {
+                executor.shutdownNow();
+            }
+        } catch (InterruptedException e) {
+            executor.shutdownNow();
+        }
+    }
+
+    public static void main(String[] args) throws ExecutionException, InterruptedException {
+        FutureDemo demo = new FutureDemo();
+        System.out.println("Starting calculation");
+        Future<Integer> result0 = demo.calculate(2);
+        System.out.println("2 x 2 = " + result0.get());
+
+        Future<Integer> result1 = demo.calculate(4);
+        while (!result1.isDone()){
+            System.out.println("calculating...");
+            Thread.sleep(300);
+        }
+
+        System.out.println("4 x 4 = " + result1.get());
+
+        demo.shutdownExecutor();
+        System.out.println("exit");
+        System.exit(0);
+    }
+
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/JavaStreams.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/JavaStreams.java
new file mode 100644
index 0000000000000000000000000000000000000000..cb5927302034cf20ba28c14114a1f50b50619076
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/JavaStreams.java
@@ -0,0 +1,32 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+//based on https://mkyong.com/java8/java-8-parallel-streams-examples/
+public class JavaStreams {
+
+    public static boolean isPrime(int number) {
+        if (number <= 1) return false;
+        return !IntStream.rangeClosed(2, number / 2).anyMatch(i -> number % i == 0);
+    }
+
+    public static void main(String[] args) {
+
+        long start = System.currentTimeMillis();
+
+        long count = Stream.iterate(0, n -> n + 1)
+                .limit(1_000_000)
+                .parallel()
+                .filter(JavaStreams::isPrime)
+                .peek(x -> System.out.format("%s\t", x))
+                .count();
+
+        long end = System.currentTimeMillis();
+
+        long duration = end - start;
+
+        System.out.println("\n\nDuration: " + duration/1000.0);
+    }
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateAtomic.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateAtomic.java
new file mode 100644
index 0000000000000000000000000000000000000000..5fb6d2d9c340a516160a28fa5d15fce3ecb2c616
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateAtomic.java
@@ -0,0 +1,45 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class LostUpdateAtomic {
+
+    private AtomicInteger counter = new AtomicInteger(0);
+
+    public void increment(){
+        counter.incrementAndGet();
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+        LostUpdateAtomic lu = new LostUpdateAtomic();
+
+        Thread t0 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        t0.start();
+        t1.start();
+
+        t0.join();
+        t1.join();
+
+        System.out.println("Counter value: " + lu.counter.get());
+    }
+
+
+}
diff --git a/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateSynchronized.java b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateSynchronized.java
new file mode 100644
index 0000000000000000000000000000000000000000..d2929ca45be9a793f86f6f7ff5a0d3f469216be2
--- /dev/null
+++ b/src/main/java/de/hdm/jordine/vorlesung/concurrency/solutions/LostUpdateSynchronized.java
@@ -0,0 +1,46 @@
+package de.hdm.jordine.vorlesung.concurrency.solutions;
+
+public class LostUpdateSynchronized {
+
+    private int counter = 0;
+
+    public void increment(){
+        counter++;
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+        Object monitor0 = new Object();
+        Object monitor1 = new Object();
+
+        LostUpdateSynchronized lu = new LostUpdateSynchronized();
+
+        Thread t0 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        Thread t1 = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < 10000; i++) {
+                    lu.increment();
+                }
+            }
+        });
+
+        t0.start();
+        t1.start();
+
+        //t0.join();
+        //t1.join();
+
+        System.out.println("Counter value: " + lu.counter);
+    }
+
+
+}
diff --git a/website/assignments/bewertungsbogen.xlsx b/website/assignments/bewertungsbogen.xlsx
index 1280b71ec19b6063d00fa9d930e77be9327a9ce1..1936851b814da32e84308bccbb79fd9641006984 100644
Binary files a/website/assignments/bewertungsbogen.xlsx and b/website/assignments/bewertungsbogen.xlsx differ
diff --git a/website/concurrency.html b/website/concurrency.html
new file mode 100644
index 0000000000000000000000000000000000000000..65094a3ec77bee007e0b476e365881e49d993059
--- /dev/null
+++ b/website/concurrency.html
@@ -0,0 +1,419 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Parallele Programmierung</title>
+    <meta charset="utf-8">
+      <link href="css/hdm.css" rel="stylesheet"></link>
+      <style>
+          /* yanone-kaffeesatz-regular - latin */
+          @font-face {
+              font-family: 'Yanone Kaffeesatz';
+              font-style: normal;
+              font-weight: 400;
+              src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */
+              src: local(''),
+              url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+              url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
+              url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */
+              url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
+              url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
+          }
+          /* noto-serif-regular - latin */
+          @font-face {
+              font-family: 'Noto Serif';
+              font-style: normal;
+              font-weight: 400;
+              src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */
+              src: local(''),
+              url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+              url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
+              url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */
+              url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
+              url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */
+          }
+          /* ubuntu-mono-regular - latin */
+          @font-face {
+              font-family: 'Ubuntu Mono';
+              font-style: normal;
+              font-weight: 400;
+              src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
+              src: local(''),
+              url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+              url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
+              url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
+          }
+          /* ubuntu-mono-italic - latin */
+          @font-face {
+              font-family: 'Ubuntu Mono';
+              font-style: italic;
+              font-weight: 400;
+              src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
+              src: local(''),
+              url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+              url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
+              url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
+          }
+          /* ubuntu-mono-700 - latin */
+          @font-face {
+              font-family: 'Ubuntu Mono';
+              font-style: normal;
+              font-weight: 700;
+              src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
+              src: local(''),
+              url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+              url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
+              url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
+              url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
+          }
+
+          body { font-family: 'Noto Serif'; }
+          h1, h2, h3 {
+              font-family: 'Yanone Kaffeesatz';
+              font-weight: normal;
+          }
+          .remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
+      </style>
+  </head>
+  <body>
+    <textarea id="source">
+
+class: center, middle, first
+
+# Software-Entwicklung 3
+
+## Parallele Programmierung
+
+---
+
+# Agenda
+
+1. Recap
+2. Parallele Programmierung
+3. https://www.vogella.com/tutorials/JavaConcurrency/article.html
+4. https://www.baeldung.com/java-concurrency
+
+* Warum wird parallele Programmierung benötigt?
+* Prozesse <-> Threads
+* Amdahls Law
+* Wie funktioniert parallele Programmierung?
+* Wie funktioniert parallele Programmierung in Java?
+  * `Thread`
+  * `Runnable`
+  * `wait()`, `join()`, `notify()`
+  * `volatile`
+  * `Executor`-Framework
+* Probleme bei paralleler Programmierung
+  * `shared state`
+  * Lost Update/Race conditions/Dirty Read
+  * Dead Lock -> https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html 
+* Möglichkeiten, Concurrency-Probleme in Java zu beheben
+  * Locks/Monitor-Objekte/`synchronized`
+  * `Atmoic`-Klassen
+  * `Concurrent`-Collections
+  * `Future`s, `Callable`
+  * Funktionale Programmierung -> Java Streams
+    * Was bedeutet funktionale Programmierung?
+* Was ist Skalierung? Horizontale Skalierung <-> vertikale Skalierung
+
+---
+
+# Recap: Was haben wir in der letzten Vorlesung besprochen?
+
+* SQL
+* NoSQL
+
+> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
+
+---
+class: center, middle
+# Welche Formen der Kommunikationsbeziehungen kennen Sie in der (objektorientierten) Programmierung?
+
+---
+# Kommunikationsbeziehungen
+
+Beispiele:
+
+* lokale Schnittstellen
+    * API (lokal)
+* Remote Schnittstellen
+  * RPC
+  * RESTful-APIs
+  * SOAP-APIs
+  * Messaging-APIs/Event-based APIs
+
+---
+# Gruppierung der Schnittstellenarten
+
+## Synchrone Schnittstellen
+
+## Asynchrone Schnittstellen
+
+---
+# Definition synchrone Schnittstelle
+
+> Der Sender **blockiert** bis vom Empfänger eine Antwort geschickt wurde.
+
+## Beispiele für synchrone Kommunikation
+
+* HTTP
+* SOAP
+* GraphQL
+* RPC (z.B. RMI, gRPC)
+* REST
+
+---
+
+# Ablauf synchrone Schnittstelle (vereinfacht)
+
+## Sender
+1. Verfassen einer Nachricht
+2. Verpacken der Nachricht (_Marshalling_)
+3. Absenden der Nachricht
+4. _Warten auf Antwort_
+5. Empfangen der Antwort-Nachricht
+6. Auspacken der Antwort-Nachricht
+7. Verarbeiten der Antwort-Nachricht
+
+---
+# Ablauf synchrone Schnittstelle (vereinfacht)
+
+## Empfänger
+1. _Warten auf eingehende Nachrichten_
+2. Empfangen der Nachricht
+3. Auspacken der Nachricht
+4. Verarbeiten der Nachricht
+5. Verfassen der Antwort-Nachricht
+6. Verpacken der Antwort-Nachricht
+7. Verschicken der Antwort-Nachricht
+
+---
+# Ablauf synchrone Schnittstelle
+
+**Neu!**
+
+> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
+
+---
+# Was ist REST?
+
+> REST: Representational State Transfer
+
+Softwarearchitekturstil
+
+---
+# Grundprinzipien
+
+_nach [Wikipedia, 2022](https://de.wikipedia.org/wiki/Representational_State_Transfer)_
+
+* Client/Server
+* Zustandslosigkeit
+* Caching
+* Einheitliche Schnittstelle
+  * Adressierbarkeit von Ressourcen
+  * Repräsentationen zur Veränderung von Ressourcen
+  * Selbstbeschreibende Nachrichten
+  * „Hypermedia as the Engine of Application State“ (HATEOAS)
+* Mehrschichtige Systeme
+* Code on Demand (optional)
+---
+# REST-URIs
+
+> URI: Uniform Resource Identifier
+
+Mögliche URI-Muster:
+* `<protocol>://<service-name>/<resource-type>/<resource-id>`
+* `<resource-type>/<resource-id>`
+* `<protocol>://<service-name>/<resource-type>/<resource-id>/<resource-details>`
+* `<protocol>://<service-name>/<api-version>/<resource-type>/<resource-id>`
+
+Beispiele:
+* `https://music-mamager.app/songs/112233`
+* `https://music-mamager.app/songs/112233/play`
+* `https://music-mamager.app/songs/112233/artist`
+* `/v3/songs/112233/artist/json`
+
+---
+# REST im Einsatz
+
+* Verwendung auf Basis von HTTP/HTTPS
+* Nutzen der [HTTP-Verben](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)
+  * `POST`
+  * `GET`
+  * `DELETE`
+  * `PUT` (entspricht einem Update)
+  * ...
+* Nutzen der HTTP-Status-Codes für Antworten
+  * [Ãœbersicht der HTTP-Status-Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
+
+---
+# REST-APIs mit OpenAPI 3/Swagger
+
+* API-Spezifikation 
+* API-Dokumentation
+* API-Generierung
+* Testumgebung
+
+[Petstore Demo Projekt](https://petstore.swagger.io/)
+
+---
+# REST mit Spring Boot (I)
+
+* Alternative zu `JAX-WS`
+* Maven-Dependency hinzufügen (`spring-boot-starter-web`)
+
+```xml
+<dependency>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-web</artifactId>
+    <version>2.7.0</version>
+    <!-- ... -->
+</dependency>
+```
+* Erstellen einer Klasse, die mit `@RestController` annotiert wird
+* Annotieren der Methoden mit geeigneter HTTP-Verb Annotation (z.B. `@GetMapping`) und zuweisen des Resource-Pfads (z.B. `/songs`)
+* Mapping der URL-Parameter zu Java-Parametern mit der `@RequestParam(value = "name", defaultValue = "Song 2")`
+
+---
+# REST mit Spring Boot (II)
+
+Start der Anwendung:
+
+```java
+@SpringBootApplication
+public class RestServiceApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(RestServiceApplication.class, args);
+	}
+
+}
+```
+---
+# REST mit Spring Boot (III)
+
+_Quelle: ["Building a RESTful Web Service", spring.io, 2022](https://spring.io/guides/gs/rest-service/)_
+
+```java
+package com.example.restservice;
+
+public class Greeting {
+
+	private final long id;
+	private final String content;
+
+	public Greeting(long id, String content) {
+		this.id = id;
+		this.content = content;
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public String getContent() {
+		return content;
+	}
+}
+```
+
+---
+# REST mit Spring Boot (IV)
+
+```java
+package com.example.restservice;
+
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class GreetingController {
+
+	private static final String template = "Hello, %s!";
+	private final AtomicLong counter = new AtomicLong();
+
+	@GetMapping("/greeting")
+	public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
+		return new Greeting(counter.incrementAndGet(), String.format(template, name));
+	}
+}
+```
+---
+# REST-Demo im Projekt
+
+> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
+
+---
+class: center, middle
+
+# Asynchrone Kommunikationsbeziehungen
+
+---
+# Definition asynchrone Schnittstelle
+
+> Sender **blockiert nicht** bis vom Empfänger eine Antwort geschickt wurde.
+
+## Beispiele asynchrone Kommunikation
+
+* Chats
+* E-Mail
+* Message Broker/Queues (implementierungsabhängig)
+
+---
+# Message Broker
+
+_nach: "Learn Microservices with Spring Boot", Moisés Macero García, apress, 2020, S. 216_
+
+<img alt="Schematische Darstellung Message Broker" src="img/schnittstellen/message_broker.png" width="100%"/>
+
+---
+# Ablauf asynchrone Schnittstelle (vereinfacht)
+
+## Sender
+1. Verfassen einer Nachricht
+2. Verpacken der Nachricht (_Marshalling_)
+3. Absenden der Nachricht
+4. _Weiter im Programmfluss_
+5. _Ggf. Empfangen der Antwort-Nachricht (nach Zeitraum X)_
+6. _Ggf. Auspacken der Antwort-Nachricht_
+7. _Ggf. Verarbeiten der Antwort-Nachricht_
+
+---
+# Ablauf asynchrone Schnittstelle (vereinfacht)
+
+## Empfänger
+1. _Warten auf eingehende Nachrichten_
+2. Empfangen der Nachricht
+3. Auspacken der Nachricht
+4. Verarbeiten der Nachricht
+5. _Ggf. Verfassen der Antwort-Nachricht_
+6. _Ggf. Verpacken der Antwort-Nachricht_
+7. _Ggf. Verschicken der Antwort-Nachricht_
+
+---
+# Backup Themen: Software im Betrieb
+
+* Eventual consistency
+* Monitoring
+* Logging
+* Security
+* Patching
+* Releaseplanung
+* Downtimes
+* Dokumentation/Schulungen
+
+    </textarea>
+    <script src="js/remark.min.js">
+    </script>
+    <script>
+      var slideshow = remark.create();
+    </script>
+  </body>
+</html>
\ No newline at end of file