Leitfaden zu LinkRest

Anleitung zu LinkRest

1. Überblick

LinkRest ist ein Open-Source-Framework zum Erstellen datengesteuerter REST-Webdienste. Es basiert aufJAX-RS undApache Cayenne ORM und verwendet ein HTTP / JSON-basiertes Nachrichtenprotokoll.

Grundsätzlich soll dieses Framework eine einfache Möglichkeit bieten, unseren Datenspeicher im Web verfügbar zu machen.

In den folgenden Abschnitten sehen wir uns an, wie wir einen REST-Webdienst erstellen können, um mitLinkRest auf ein Datenmodell zuzugreifen.

2. Maven Abhängigkeiten

Um mit der Bibliothek arbeiten zu können, müssen wir zuerst die Abhängigkeit vonlink-resthinzufügen:


    com.nhl.link.rest
    link-rest
    2.9

Dies bringt auch das Artefaktcayenne-serverein.

Darüber hinaus verwenden wirJersey alsJAX-RS-Implementierung. Daher müssen wir die Abhängigkeit vonjersey-container-servlet sowiejersey-media-moxy für die Serialisierung von JSON-Antworten hinzufügen:


    org.glassfish.jersey.containers
    jersey-container-servlet
    2.25.1


    org.glassfish.jersey.media
    jersey-media-moxy
    2.25.1

In unserem Beispiel arbeiten wir mit einer speicherinternenH2-Datenbank, da die Einrichtung einfacher ist. Infolgedessen fügen wir auchh2 hinzu:


    com.h2database
    h2
    1.4.196

3. Cayenne Datenmodell

Das Datenmodell, mit dem wir arbeiten, enthält eineDepartment- und eineEmployee-Entität, die eine Eins-zu-Viele-Beziehung darstellen:

image

Wie erwähnt,LinkRest works with data objects generated using Apache Cayenne ORM. Die Arbeit mitCayenne ist nicht das Hauptthema dieses Artikels. Weitere Informationen finden Sie unterApache Cayenne documentation.

Wir speichern das ProjektCayennein einer Dateicayenne-linkrest-project.xml.

Nach dem Ausführen voncayenne-maven-plugin werden zwei abstrakteDepartment_ and Employee_-Klassen generiert, die dieCayenneDataObject-Klasse sowie zwei daraus abgeleitete konkrete Klassen,Department undEmployee.

Diese letzteren Klassen können mitLinkRest angepasst und verwendet werden.

4. LinkRest Anwendungsstart

Im nächsten Abschnitt werden wir REST-Endpunkte schreiben und testen. Um sie ausführen zu können, müssen wir unsere Laufzeit einrichten.

Da wirJersey alsJAX-RS-Implementierung verwenden, fügen wir eine Klasse hinzu, dieResourceConfig erweitert und das Paket angibt, das die Klassen enthält, in denen wir die REST-Endpunkte definieren:

@ApplicationPath("/linkrest")
public class LinkRestApplication extends ResourceConfig {

    public LinkRestApplication() {
        packages("com.example.linkrest.apis");

        // load linkrest runtime
    }
}

Im selben Konstruktor müssen wir dieLinkRestRuntime erstellen und imJersey-Container registrieren. Diese Klasse basiert auf dem ersten Laden derCayenneRuntime:

ServerRuntime cayenneRuntime = ServerRuntime.builder()
  .addConfig("cayenne-linkrest-project.xml")
  .build();
LinkRestRuntime lrRuntime = LinkRestBuilder.build(cayenneRuntime);
super.register(lrRuntime);

Schließlich müssen wir die Klasse zuweb.xml hinzufügen:


    linkrest
    org.glassfish.jersey.servlet.ServletContainer
        
            javax.ws.rs.Application
            com.example.LinkRestApplication
        
    1


    linkrest
    /*

5. REST-Ressourcen

Nachdem wir unsere Modellklassen erhalten haben, können wir mit dem Schreiben von REST-Ressourcen beginnen.

DieREST endpoints are created using standard JAX-RS annotations, while the response is built using the LinkRest class.

Unser Beispiel besteht darin, eine Reihe von CRUD-Endpunkten zu schreiben, die mit verschiedenen HTTP-Methoden auf die/department-URL zugreifen.

Erstellen wir zunächst die KlasseDepartmentResource, die/department zugeordnet ist:

@Path("department")
@Produces(MediaType.APPLICATION_JSON)
public class DepartmentResource {

    @Context
    private Configuration config;

    // ...
}

Die KlasseLinkRest benötigt eine Instanz der KlasseJAX-RS Configuration, die unter Verwendung der AnnotationContext eingefügt wird, die auch vonJAX-RS bereitgestellt wird.

Als Nächstes schreiben wir weiter jeden der Endpunkte, die aufDepartment-Objekte zugreifen.

5.1. Entitäten mit POST erstellen

Um eine Entität zu erstellen, stellt die KlasseLinkRestdie Methodecreate()bereit, die ein ObjektUpdateBuilderzurückgibt:

@POST
public SimpleResponse create(String data) {
    return LinkRest.create(Department.class, config).sync(data);
}

Der Datenparameter kann entweder ein einzelnes JSON-Objekt sein, dasDepartment darstellt, oder ein Array von Objekten. Dieser Parameter wird mit der Methodesync() anUpdateBuilder gesendet, um ein oder mehrere Objekte zu erstellen und die Datensätze in die Datenbank einzufügen. Danach gibt die MethodeSimpleResponse zurück.

Die Bibliothek definiert 3 zusätzliche Formate für Antworten:

  • DataResponse<T> - eine Antwort, die eine Sammlung vonT darstellt

  • MetadataResponse<T> - enthält Metadateninformationen zum Typ

  • SimpleResponse - Ein Objekt, das zweisuccess- undmessage-Attribute enthält

Verwenden Sie als Nächstescurl, um der Datenbank einenDepartment-Datensatz hinzuzufügen:

curl -i -X POST -H "Content-Type:application/json"
  -d "{"name":"IT"}" http://localhost:8080/linkrest/department

Infolgedessen gibt der Befehl die Attribute201 Created undsuccesszurück:

{"success":true}

Wir können auch mehrere Objekte erstellen, indem wir ein JSON-Array senden:

curl -i -X POST -H "Content-Type:application/json"
  -d "[{"name":"HR"},{"name":"Marketing"}]"
  http://localhost:8080/linkrest/department

5.2. Entitäten mit GET lesen

Die Hauptmethode zum Abfragen von Objekten ist dieselect()-Methode aus derLinkRest-Klasse. Dies gibt einSelectBuilder-Objekt zurück, mit dem wir zusätzliche Abfrage- oder Filtermethoden verketten können.

Erstellen wir einen Endpunkt in der KlasseDepartmentResource, der alle Objekte vonDepartmentin der Datenbank zurückgibt:

@GET
public DataResponse getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config).uri(uriInfo).get();
}

Der Aufruf vonuri() legt die Anforderungsinformationen fürSelectBuilder fest, während get () eine Sammlung vonDepartments zurückgibt, die alsDataResponse<Department>-Objekt verpackt sind.

Werfen wir einen Blick auf die Abteilungen, die wir hinzugefügt haben, bevor wir diesen Endpunkt verwenden:

curl -i -X GET http://localhost:8080/linkrest/department

Die Antwort hat die Form eines JSON-Objekts mit einem Array vondataund einer Eigenschaft vontotal:

{"data":[
  {"id":200,"name":"IT"},
  {"id":201,"name":"Marketing"},
  {"id":202,"name":"HR"}
],
"total":3}

Um eine Sammlung von Objekten abzurufen, können Sie alternativ auch ein einzelnes Objekt zurückerhalten, indem SiegetOne() anstelle vonget() verwenden.

Fügen wir einen Endpunkt hinzu, der/department/{departmentId} zugeordnet ist und ein Objekt mit einer bestimmten ID zurückgibt. Zu diesem Zweck filtern wir die Datensätze mit der MethodebyId():

@GET
@Path("{id}")
public DataResponse getOne(@PathParam("id") int id,
  @Context UriInfo uriInfo) {
    return LinkRest.select(Department.class, config)
      .byId(id).uri(uriInfo).getOne();
}

Dann können wir eine GET-Anfrage an diese URL senden:

curl -i -X GET http://localhost:8080/linkrest/department/200

Das Ergebnis ist eindata-Array mit einem Element:

{"data":[{"id":200,"name":"IT"}],"total":1}

5.3. Aktualisieren von Entitäten mit PUT

Um Datensätze zu aktualisieren, können wir die Methodeupdate() odercreateOrUpdate() verwenden. Letzterer aktualisiert Datensätze, falls vorhanden, oder erstellt sie, falls nicht:

@PUT
public SimpleResponse createOrUpdate(String data) {
    return LinkRest.createOrUpdate(Department.class, config).sync(data);
}

Ähnlich wie in den vorherigen Abschnitten kann das Argumentdataein einzelnes Objekt oder ein Array von Objekten sein.

Aktualisieren wir eine der zuvor hinzugefügten Abteilungen:

curl -i -X PUT -H "Content-Type:application/json"
  -d "{"id":202,"name":"Human Resources"}"
  http://localhost:8080/linkrest/department

Dies gibt ein JSON-Objekt mit einer Erfolgs- oder Fehlermeldung zurück. Anschließend können wir überprüfen, ob der Name der Abteilung mit der ID 202 geändert wurde:

curl -i -X GET http://localhost:8080/linkrest/department/202

Dieser Befehl gibt das Objekt mit dem neuen Namen zurück:

{"data":[
  {"id":202,"name":"Human Resources"}
],
"total":1}

5.4. Entitäten mitDELETE entfernen

Um ein Objekt zu entfernen, können Sie die Methodedelete() aufrufen, mit derDeleteBuilder erstellt wird, und dann den Primärschlüssel des Objekts angeben, das wir mit der Methodeid() löschen möchten:

@DELETE
@Path("{id}")
public SimpleResponse delete(@PathParam("id") int id) {
    return LinkRest.delete(Department.class, config).id(id).delete();
}

Dann können wir diesen Endpunkt mitcurl aufrufen:

curl -i -X DELETE http://localhost:8080/linkrest/department/202

5.5. Arbeiten mit Beziehungen zwischen Entitäten

LinkRest enthält auch Methoden, die das Arbeiten mit Beziehungen zwischen Objekten erleichtern.

DaDepartment eine Eins-zu-Viele-Beziehung zuEmployee hat, fügen wir einen Endpunkt von/department/{departmentId}/employeeshinzu, der auf eine Klasse vonEmployeeSubResourcezugreift:

@Path("{id}/employees")
public EmployeeSubResource getEmployees(
  @PathParam("id") int id, @Context UriInfo uriInfo) {
    return new EmployeeSubResource(id);
}

Die KlasseEmployeeSubResourceentspricht einer Abteilung, daher verfügt sie über einen Konstruktor, der eine Abteilungs-ID festlegt, sowie über die InstanzConfiguration:

@Produces(MediaType.APPLICATION_JSON)
public class EmployeeSubResource {
    private Configuration config;

    private int departmentId;

    public EmployeeSubResource(int departmentId, Configuration configuration) {
        this.departmentId = departmentId;
        this.config = config;
    }

    public EmployeeSubResource() {
    }
}

Beachten Sie, dass ein Standardkonstruktor erforderlich ist, damit das Objekt als JSON-Objekt serialisiert werden kann.

Definieren wir als Nächstes einen Endpunkt, an dem alle Mitarbeiter einer Abteilung abgerufen werden:

@GET
public DataResponse getAll(@Context UriInfo uriInfo) {
    return LinkRest.select(Employee.class, config)
      .toManyParent(Department.class, departmentId, Department.EMPLOYEES)
      .uri(uriInfo).get();
}

In diesem Beispiel haben wir dietoManyParent()-Methode derSelectBuilder verwendet, um nur die Objekte mit einem bestimmten übergeordneten Element abzufragen.

Die Endpunkte für die POST-, PUT- und DELETE-Methoden können auf ähnliche Weise erstellt werden.

Um Mitarbeiter zu einer Abteilung hinzuzufügen, können wir den Endpunkt vondepartments/{departmentId}/employeesmit der POST-Methode aufrufen:

curl -i -X POST -H "Content-Type:application/json"
  -d "{"name":"John"}" http://localhost:8080/linkrest/department/200/employees

Senden Sie dann eine GET-Anfrage, um die Mitarbeiter der Abteilung anzuzeigen:

curl -i -X GET "http://localhost:8080/linkrest/department/200/employees
Dies gibt ein JSON-Objekt mit einem Datenarray zurück
{"data":[{"id":200,"name":"John"}],"total":1}

6. Anpassen der Antwort mit Anforderungsparametern

LinkRest bietet eine einfache Möglichkeit, die Antwort anzupassen, indem der Anforderung bestimmte Parameter hinzugefügt werden. Diese können zum Filtern, Sortieren, Paginieren oder Einschränken der Attributmenge der Ergebnismenge verwendet werden.

6.1. Filtern

Wir können die Ergebnisse basierend auf den Werten von Attributen filtern, indem wir den ParametercayenneExp verwenden. Wie der Name schon sagt, folgt dies dem Format vonCayenne expressions.

Senden wir eine Anfrage, die nur Abteilungen mit dem Namen "IT" zurückgibt:

curl -i -X GET http://localhost:8080/linkrest/department?cayenneExp=name='IT'

6.2. Sortierung

Die Parameter, die zum Sortieren einer Reihe von Ergebnissen hinzugefügt werden müssen, sindsort unddir. Das erste gibt das zu sortierende Attribut und das zweite die Sortierrichtung an.

Sehen wir uns alle Abteilungen nach Namen sortiert an:

curl -i -X GET "http://localhost:8080/linkrest/department?sort=name&dir=ASC"

6.3. Seitennummerierung

Die Bibliothek unterstützt die Paginierung durch Hinzufügen der Parameterstart undlimit:

curl -i -X GET "http://localhost:8080/linkrest/department?start=0&limit=2

6.4. Attribute auswählen

Mit den Parameterninclude undexcludekönnen wir steuern, welche Attribute oder Beziehungen im Ergebnis zurückgegeben werden.

Senden wir beispielsweise eine Anfrage, in der nur die Namen der Abteilungen angezeigt werden:

curl -i -X GET "http://localhost:8080/linkrest/department?include=name

Um die Namen sowie die Mitarbeiter einer Abteilung nur mit ihrem Namen anzuzeigen, können wir das Attributincludezweimal verwenden:

curl -i -X GET "http://localhost:8080/linkrest/department?include=name&include=employees.name

7. Fazit

In diesem Artikel haben wir gezeigt, wie wir ein Datenmodell mithilfe desLinkRest-Frameworks schnell über REST-Endpunkte verfügbar machen können.

Der vollständige Quellcode der Beispiele istover on GitHub.