# Web API in Android (JAVA) einbinden



## osion (22. Feb 2020)

Hallo miteinander

Ich will eine Web-Api mit meinem Android-Telefon ansprechen.
Umgesetzt wird das mit Java, Retrofit,Livedata, RXJava

*Der Ablauf ist Simpel:*
1. Logindaten müssen zur API gesendet werden
2. API sendet ein Session-Token
3. Alle weitere Abfragen über den Token + Benutzer-Id

*Login*
Ich habe eine Abstrakte Klasse Service, welche die Daten für das Login enthalten, z. B. SessionToken
Hier bin ich nicht sicher ob das so in Ordnung ist.


*Repository*
Das Repository enthält alle Services, welche von der API angeboten wird.

getLiveDataXY (Gibt das LiveData Objekt zum Service XY)
requestServiceXY(Das Repository fragt nach den Daten)
*Beispiel eine requestService*

```
public void requestServiceXY() {
        try {
            Single<TestData> observable = new ServiceXY().send();
            observable
                    .timeout(30, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new SingleObserver<TestData>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onSuccess(TestData response) {
                            liveDataTest.setValue(response);
                        }

                        @Override
                        public void onError(Throwable e) {
                            e.printStackTrace();
                        }
                    });
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }
```


*Mapper zum JSON in Klassen*

Die HTTP-Anfrage mache ich mit Retrofit 2, welche auch direkt das Mapping vom JSON-String übernimmt.

```
public class ResponseLogin {
    private String sessionToken;
    private String sessionExpires;
    private int userId;
    private boolean isAuthenticated;
    private ArrayList<Link> links;

}
```

Soweit ich verstehe, ist die Klasse, welche die Daten für das Mapping entählt als DTO bezeichnet und die Daten innerhalb vom DTO als DAO richtig?
Ist den den die Variabel links auch ein DAO oder ein DTO, weil Link eine eigene Klasse ist?

*Meine Frage:*

Ist es in Ordnung, wenn ich eine abstrakte Service-Klasse habe, welche über eine Klasse die Benutzerdaten sowie die Session-Daten speichert oder wäre eine andere Möglichkeit zu Bevorzugen?
Ist beim JSON-Mapping, die Klasse, welche die Daten enthält ein DTO und die Daten darin sind DAO's?
Ist der Link bei der Variabel links ein Dao oder ein DTO (weil eigene Klasse)?


----------



## mihe7 (22. Feb 2020)

Ein DAO ist einfach ein Objekt, das den Zugriff auf eine Datenquelle (i.d.R. eine DB) kapselt. Dein Repository käme diesem am nächsten. 

Ein DTO ist dagegen ein Objekt, das einerseits die Daten repräsentiert, die über das Netzwerk übertragen werden sollen und andererseits ggf. die Serialisierung/Deserialisierung übernimmt. Der Sinn eines DTOs besteht einzig darin, Daten gebündelt über das Netzwerk zu übertragen.


----------



## osion (23. Feb 2020)

mihe7 hat gesagt.:


> Ein DAO ist einfach ein Objekt, das den Zugriff auf eine Datenquelle (i.d.R. eine DB) kapselt. Dein Repository käme diesem am nächsten.
> 
> Ein DTO ist dagegen ein Objekt, das einerseits die Daten repräsentiert, die über das Netzwerk übertragen werden sollen und andererseits ggf. die Serialisierung/Deserialisierung übernimmt. Der Sinn eines DTOs besteht einzig darin, Daten gebündelt über das Netzwerk zu übertragen.



Das heisst:
1. Die Klasse die für das Mapping vom JSON-String (Server response) verwendet wird ist ein DTO
2. Die Klasse die den Inhalt zum versenden der Daten (zum Server verwendet wird ist ein DTO (Es ist möglich Retrofit eine Klasse mit den Inhalt mitzugeben, statt alles manuell)

Soweit richtig?


----------



## mihe7 (23. Feb 2020)

Das Problem ist, dass Du versuchst, Objekte nach Patterns zu kategorisieren. Der Begriff DTO stammt vom gleichnamigen Entwurfsmuster, bei dem es darum geht, Daten für den Transport über das Netzwerk zusammenzufassen, *um* *unnötige* Aufrufe über das Netzwerk zu sparen.

Wenn Du einen Kunden abrufst, übermittelst Du halt das Kundenobjekt. Das macht aus dem Kundenobjekt nicht automatisch ein DTO (i. S. d. Patterns), da hierfür das Pattern nicht benötigt wird¹.

Wenn Du dagegen auch den Umsatz, die Zahl der Bestellungen und Rechnungen brauchst, dann würde das normalerweise dazu führen, dass Du

1. den Kunden abrufst
2. den Umsatz zum Kunden abrufst
3. die Zahl der Bestellungen abrufst
4. die Zahl der Rechnungen abrufst

Das heißt, Du müsstest vier Anfragen und vier Antworten über das Netzwerk schicken. Also erstellt man ein DTO, das diese Dinge zusammenfasst. Dann gibt es eine Anfrage, die mit dem DTO beantwortet wird. 

¹ natürlich könnte man argumentieren, dass man Namen, Vornamen etc. ggf. auch einzeln abrufen müsste und daher das Kundenobjekt ein DTO darstellt. Dann betrachtet man aber alles, was mehr als einen primitiven Wert zurückgibt, als DTO. Gegenargument: die Entities existieren bereits, dem entsprechend gibt es kein Problem, das mit einem Pattern (konkret dem DTO) gelöst werden müsste.


----------

