Inleiding tot RESTX

1. Overzicht

In deze zelfstudie maken we een rondleiding door het lichtgewicht Java REST-framework RESTX.

2. Kenmerken

Het bouwen van een RESTful API is vrij eenvoudig met het RESTX-framework. Het heeft alle standaardinstellingen die we van een REST-framework kunnen verwachten, zoals het aanbieden en gebruiken van JSON, query- en padparameters, routerings- en filtermechanismen, gebruiksstatistieken en monitoring.

RESTX wordt ook geleverd met een intuïtieve webconsole voor beheerders en een installatieprogramma voor de opdrachtregel voor eenvoudig opstarten.

Het is ook gelicentieerd onder de Apache License 2 en wordt onderhouden door een gemeenschap van ontwikkelaars. De minimale Java-vereiste voor RESTX is JDK 7.

3. Configuratie

RESTX wordt geleverd met een handige shell / command-app die handig is om snel een Java-project op te starten.

We moeten de app eerst installeren voordat we verder kunnen gaan. De gedetailleerde installatie-instructies zijn hier beschikbaar.

4. Core-plug-ins installeren

Nu is het tijd om de kernplug-ins te installeren om een ​​app vanuit de shell zelf te kunnen maken.

Laten we in de RESTX-shell de volgende opdracht uitvoeren:

shell installeren

Het zal ons dan vragen om de plug-ins te selecteren voor installatie. We moeten het nummer selecteren waarnaar verwijst io.restx: restx-core-shell. De shell wordt automatisch opnieuw opgestart zodra de installatie is voltooid.

5. Shell App Bootstrap

Met behulp van de RESTX-shell is het erg handig om een ​​nieuwe app op te starten. Het biedt een wizard-gebaseerde gids.

We beginnen met het uitvoeren van de volgende opdracht op de shell:

app nieuw

Deze opdracht activeert de wizard. Vervolgens kunnen we kiezen voor de standaardopties of deze wijzigen volgens onze vereisten:

Omdat we ervoor hebben gekozen om een pom.xml, het project kan eenvoudig worden geïmporteerd in elke standaard Java IDE.

In enkele gevallen moeten we de IDE-instellingen mogelijk aanpassen.

Onze volgende stap is om het project te bouwen:

mvn schone installatie -DskipTests

Zodra de build is gelukt, kunnen we het AppServer class als een Java-applicatie van de IDE. Dit zal de server starten met de admin console, luisterend op poort 8080.

We kunnen bladeren //127.0.0.1:8080/api/@/ui en bekijk de basisinterface.

De routes die beginnen met /@/ worden gebruikt voor de beheerconsole, wat een gereserveerd pad is in RESTX.

Om in te loggen op de admin console kunnen we de standaard gebruikersnaam “admin en het wachtwoord dat we hebben opgegeven tijdens het maken van de app.

Laten we, voordat we met de console spelen, de code verkennen en begrijpen wat de wizard heeft gegenereerd.

6. Een RESTX-bron

De routes zijn gedefinieerd in <main_package> .rest.HelloResource klasse:

@Component @RestxResource openbare klasse HelloResource {@GET ("/ message") @RolesAllowed (Roles.HELLO_ROLE) openbaar bericht sayHello () {retourneer nieuw bericht (). SetMessage (String.format ("hallo% s, het is% s" , RestxSession.current (). GetPrincipal (). Get (). GetName (), DateTime.now (). ToString ("HH: mm: ss"))); }}

Het is meteen duidelijk dat RESTX standaard J2EE-annotaties gebruikt voor beveiliging en REST-bindingen. Het gebruikt voor het grootste deel zijn eigen annotaties voor afhankelijkheidsinjectie.

RESTX ondersteunt ook veel redelijke standaardinstellingen voor het toewijzen van methodeparameters aan het verzoek.

En, naast deze standaard annotaties is @RestxResource, die het declareert als een bron die RESTX herkent.

Het basispad wordt toegevoegd in het src / main / webapp / WEB-INF / web.xml. In ons geval is het / api, zodat we een GET-verzoek kunnen sturen naar // localhost: 8080 / api / bericht, uitgaande van de juiste authenticatie.

De Bericht class is slechts een Java-bean die RESTX serialiseert naar JSON.

We beheren de gebruikerstoegang door het Rollen toegestaan annotatie met de HELLO_ROLE die is gegenereerd door de bootstrapper.

7. De moduleklasse

Zoals eerder opgemerkt, gebruikt RESTX J2EE-standaard afhankelijkheidsinjectie-annotaties, zoals @Genaamd, en vindt zijn eigen waar nodig, waarschijnlijk op basis van het Dagger-raamwerk voor @Module en @Biedt.

Het gebruikt deze om de hoofdmodule van de applicatie te maken, die onder andere het admin-wachtwoord definieert:

@Module openbare klasse AppModule {@ Biedt openbare SignatureKey signatureKey () {retourneer nieuwe SignatureKey ("restx-demo -44749418370 restx-demo 801f-4116-48f2-906b" .getBytes (Charsets.UTF_8)); } @Provides @Named ("restx.admin.password") public String restxAdminPassword () {retourneer "1234"; } @Biedt openbare ConfigSupplier appConfigSupplier (ConfigLoader configLoader) {return configLoader.fromResource ("restx / demo / instellingen"); } // andere providermethoden om componenten te maken}

@Module definieert een klasse die andere componenten kan definiëren, vergelijkbaar met @Module in Dagger, of @Configuratie in de lente.

@Biedt stelt een component programmatisch bloot, zoals @Biedt in Dagger, of @Boon in de lente.

En, ten slotte, de @Genaamd annotatie wordt gebruikt om de naam van de geproduceerde component aan te geven.

AppModule biedt ook een SignatureKey gebruikt om inhoud te ondertekenen die naar de klanten is verzonden. Tijdens het aanmaken van de sessie voor de voorbeeld-app zal dit bijvoorbeeld een cookie plaatsen, ondertekend met de geconfigureerde sleutel:

HTTP / 1.1 200 OK ... Set-Cookie: RestxSessionSignature-restx-demo = "ySfv8FejvizMMvruGlK3K2hwdb8 ="; RestxSession-restx-demo = "..." ...

En bekijk de documentatie over de componentenfabriek / afhankelijkheid van RESTX voor meer informatie.

8. De Launcher-klasse

En als laatste, de AppServer class wordt gebruikt om de applicatie uit te voeren als een standaard Java-app in een embedded Jetty-server:

openbare klasse AppServer {openbare statische laatste String WEB_INF_LOCATION = "src / main / webapp / WEB-INF / web.xml"; openbare statische laatste String WEB_APP_LOCATION = "src / main / webapp"; public static void main (String [] args) gooit Uitzondering {int port = Integer.valueOf (Optioneel.fromNullable (System.getenv ("PORT")). of ("8080")); WebServer-server = nieuwe Jetty8WebServer (WEB_INF_LOCATION, WEB_APP_LOCATION, poort, "0.0.0.0"); System.setProperty ("restx.mode", System.getProperty ("restx.mode", "dev")); System.setProperty ("restx.app.package", "restx.demo"); server.startAndAwait (); }}

Hier de dev modus wordt gebruikt tijdens de ontwikkelingsfase om functies zoals automatisch compileren mogelijk te maken, waardoor de feedbackloop over de ontwikkeling wordt verkort.

We kunnen de app verpakken als een oorlog (webarchief) bestand om te implementeren in een zelfstandige J2EE-webcontainer.

Laten we in de volgende sectie kijken hoe we de app kunnen testen.

9. Integratietesten met behulp van specificaties

Een van de sterke kenmerken van RESTX is het concept van "specificaties". Een voorbeeld spec zou er als volgt uitzien:

title: moet admin hallo zeggen gegeven: - tijd: 2013-08-28T01: 18: 00.822 + 02: 00 wts: - wanneer: | GET hallo? Who = xavier dan: | {"message": "hallo xavier, het is 01:18:00"}

De test is geschreven in een Given-When-Then-structuur binnen een YAML-bestand dat in feite definieert hoe de API moet reageren (dan) op een specifiek verzoek (wanneer) gegeven een huidige status van het systeem (gegeven).

De HalloResourceSpecTest les in src / test / resources zal de tests activeren die in de bovenstaande specificaties zijn geschreven:

@RunWith (RestxSpecTestsRunner.class) @FindSpecsIn ("specs / hallo") openbare klasse HelloResourceSpecTest {}

De RestxSpecTestsRunner class is een aangepaste JUnit-runner. Het bevat aangepaste JUnit-regels om:

  • een embedded server opzetten
  • bereid de staat van het systeem voor (volgens de gegeven sectie in de specificaties)
  • de gespecificeerde verzoeken uitgeven, en
  • controleer de verwachte reacties

De @BuienRadarNL annotatie verwijst naar het pad van de spec-bestanden waartegen de tests moeten worden uitgevoerd.

De specificatie helpt bij het schrijven van integratietests en biedt voorbeelden in de API-documenten. Specs zijn ook handig om HTTP-verzoeken te bespotten en verzoek / antwoord-paren op te nemen.

10. Handmatig testen

We kunnen ook handmatig testen via HTTP. We moeten eerst inloggen en om dit te doen, moeten we het beheerderswachtwoord hashen in de RESTX-console:

hash md5 

En dan kunnen we dat doorgeven aan de / sessies eindpunt:

curl -b u1 -c u1 -X POST -H "Content-Type: application / json" -d '{"principal": {"name": "admin", "passwordHash": "1d528266b85cf052803a57288"}}' // localhost: 8080 / api / sessies

(Merk op dat Windows-gebruikers eerst curl moeten downloaden.)

En nu, als we de sessie gebruiken als onderdeel van onze /bericht verzoek:

curl -b u1 "// localhost: 8080 / api / bericht? who = restx"

Dan krijgen we zoiets als dit:

{"message": "hallo admin, het is 09:56:51"}

11. Verkennen van de Admin Console

De beheerconsole biedt handige bronnen om de app te besturen.

Laten we de belangrijkste functies eens bekijken door naar te bladeren //127.0.0.1:8080/admin/@/ui.

11.1. API-documenten

In de sectie API-documenten staan ​​alle beschikbare routes vermeld, inclusief alle opties:

En we kunnen op individuele routes klikken en ze op de console zelf uitproberen:

11.2. Toezicht houden

De JVM-statistieken sectie toont de toepassingsstatistieken met actieve sessies, geheugengebruik en threaddump:

Onder Toepassingsstatistieken we hebben hoofdzakelijk twee categorieën elementen die standaard worden gecontroleerd:

  • BOUWEN komt overeen met de concretisering van de applicatiecomponenten
  • HTTP komt overeen met HTTP-verzoeken die worden afgehandeld door RESTX

11.3. Statistieken

Met RESTX kan de gebruiker ervoor kiezen om anonieme statistieken over de applicatie te verzamelen en te delen om informatie te geven aan de RESTX-gemeenschap. We kunnen ons gemakkelijk afmelden door de restx-stats-admin module.

De statistieken rapporteren zaken als het onderliggende besturingssysteem en de JVM-versie:

Omdat deze pagina gevoelige informatie toont,zorg ervoor dat u de configuratie-opties bekijkt.

Afgezien van deze, kan de beheerconsole ons ook helpen:

  • controleer de serverlogs (Logs)
  • bekijk de opgetreden fouten (fouten)
  • controleer de omgevingsvariabelen (Config)

12. Autorisatie

RESTX-eindpunten zijn standaard beveiligd. Dat betekent als voor elk eindpunt:

@GET ("/ greetings / {who}") openbaar bericht sayHello (String who) {return new Message (who); }

Bij een oproep zonder authenticatie wordt een 401 standaard.

Om een ​​eindpunt openbaar te maken, moeten we de @PermitAll annotatie op methode- of klassenniveau:

@PermitAll @GET ("/ greetings / {who}") openbaar bericht sayHello (String who) {return new Message (who); }

Merk op dat op klassenniveau alle methoden openbaar zijn.

Verder maakt het framework het ook mogelijk om gebruikersrollen te specificeren met behulp van de @RollenAllowed annotatie:

@RolesAllowed ("admin") @GET ("/ greetings / {who}") openbaar bericht sayHello (String who) {return new Message (who); }

Met deze annotatie controleert RESTX of de geverifieerde gebruiker ook een beheerdersrol heeft toegewezen. In het geval dat een geverifieerde gebruiker zonder beheerdersrollen toegang probeert te krijgen tot het eindpunt, retourneert de applicatie een 403 inplaats van een 401.

Standaard worden de gebruikersrollen en legitimatiegegevens in afzonderlijke bestanden op het bestandssysteem opgeslagen.

Het gebruikers-ID met het gecodeerde wachtwoord wordt dus opgeslagen onder /data/credentials.json het dossier:

{"user1": "$ 2a $ 10 $ iZluUbCseDOvKnoe", "user2": "$ 2a $ 10 $ oym3Swr7pScdiCXu"}

En de gebruikersrollen zijn gedefinieerd in /data/users.json het dossier:

[{"name": "user1", "rolls": ["hallo"]}, {"name": "user2", "rollen": []}]

In de voorbeeld-app worden de bestanden geladen in het AppModule via de FileBasedUserRepository klasse:

nieuwe FileBasedUserRepository (StdUser.class, mapper, nieuwe StdUser ("admin", ImmutableSet. of ("*")), Paths.get ("data / users.json"), Paths.get ("data / credentials.json" ), waar)

De StdUser klasse bevat de gebruikersobjecten. Het kan een aangepaste gebruikersklasse zijn, maar het moet serialiseerbaar zijn in JSON.

We kunnen natuurlijk een andere gebruiken UserRepository implementatie, zoals een die een database raakt.

13. Conclusie

Deze tutorial gaf een overzicht van het lichtgewicht op Java gebaseerde RESTX-framework.

Het framework is nog in ontwikkeling en het kan zijn dat er wat ruwe kantjes mee zitten. Bekijk de officiële documentatie voor meer details.

De voorbeeld-bootstrapped-app is beschikbaar in onze GitHub-repository.