Pengenalan kepada RESTX

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan mengikuti lawatan RESTX Java REST framework yang ringan.

2. Ciri-ciri

Membangun RESTful API cukup mudah dengan rangka RESTX. Ini memiliki semua lalai yang dapat kita harapkan dari kerangka REST seperti melayani dan menggunakan JSON, parameter pertanyaan dan jalur, mekanisme penghalaan dan penyaringan, statistik penggunaan, dan pemantauan.

RESTX juga dilengkapi dengan konsol web pentadbir intuitif dan pemasang baris perintah untuk bootstrap yang mudah.

Ia juga dilesenkan di bawah Apache License 2 dan dikendalikan oleh komuniti pemaju. Keperluan minimum Java untuk RESTX adalah JDK 7.

3. Konfigurasi

RESTX dilengkapi dengan aplikasi shell / command berguna yang berguna untuk bootstrap projek Java dengan cepat.

Kita perlu memasang aplikasi terlebih dahulu sebelum dapat meneruskannya. Arahan pemasangan terperinci boleh didapati di sini.

4. Memasang Core Plugin

Sekarang, sudah tiba masanya untuk memasang plugin teras untuk dapat membuat aplikasi dari cangkang itu sendiri.

Dalam shell RESTX, mari jalankan arahan berikut:

shell install

Ini kemudian akan meminta kita memilih pemalam untuk pemasangan. Kita perlu memilih nombor yang menunjukkan io.restx: restx-core-shell . Shell akan dimulakan semula secara automatik setelah pemasangan selesai.

5. Bootstrap Aplikasi Shell

Menggunakan shell RESTX adalah sangat mudah untuk boot aplikasi baru. Ia menyediakan panduan berasaskan ahli sihir.

Kita mulakan dengan melaksanakan perintah berikut pada shell:

app new

Perintah ini akan mencetuskan ahli sihir. Kemudian kita boleh memilih dengan pilihan lalai atau mengubahnya mengikut keperluan kita:

Oleh kerana kami telah memilih untuk menghasilkan pom.xml, projek ini dapat dengan mudah diimport ke dalam Java IDE standard apa pun.

Dalam beberapa kes, kita mungkin perlu mengubah tetapan IDE.

Langkah seterusnya adalah membina projek:

mvn clean install -DskipTests

Setelah berjaya, kita dapat menjalankan kelas AppServer sebagai Aplikasi Java dari IDE . Ini akan memulakan pelayan dengan konsol pentadbir, mendengar di port 8080.

Kita boleh melayari ke //127.0.0.1:8080/api/@/ui dan melihat UI asas.

Laluan yang bermula dengan / @ / digunakan untuk konsol pentadbir yang merupakan laluan yang dikhaskan di RESTX.

Untuk masuk ke konsol admin, kita dapat menggunakan nama pengguna lalai "admin " dan kata laluan yang kami berikan semasa membuat aplikasi.

Sebelum kita bermain-main dengan konsol, mari kita meneroka kodnya dan memahami apa yang dihasilkan oleh penyihir.

6. Sumber RESTX

Laluan ditentukan dalam < main_package> .rest.HelloResource class:

@Component @RestxResource public class HelloResource { @GET("/message") @RolesAllowed(Roles.HELLO_ROLE) public Message sayHello() { return new Message().setMessage(String.format("hello %s, it's %s", RestxSession.current().getPrincipal().get().getName(), DateTime.now().toString("HH:mm:ss"))); } }

Sudah jelas bahawa RESTX menggunakan anotasi J2EE lalai untuk keselamatan dan pengikatan REST. Sebahagian besarnya, ia menggunakan anotasi sendiri untuk suntikan kebergantungan.

RESTX juga menyokong banyak lalai yang munasabah untuk memetakan parameter kaedah kepada permintaan.

Selain itu, selain anotasi standard ini adalah @RestxResource , yang menyatakannya sebagai sumber yang dikenali oleh RESTX.

Laluan asas ditambahkan dalam src / main / webapp / WEB-INF / web.xml. Dalam kes kami, itu / api , jadi kami dapat mengirim permintaan GET ke // localhost: 8080 / api / message , dengan asumsi pengesahan yang tepat.

The Message kelas hanya kacang Java yang RESTX serializes untuk JSON.

Kami mengawal akses pengguna dengan menentukan anotasi RolesAllowed menggunakan HELLO_ROLE yang dihasilkan oleh bootstrapper.

7. Kelas Modul

Seperti yang dinyatakan sebelum ini, RESTX menggunakan anotasi suntikan ketergantungan standard J2EE, seperti @Named , dan mencipta sendiri di mana diperlukan, mungkin mengambil petunjuk dari kerangka keris untuk @Module dan @Provides.

Ia menggunakan ini untuk membuat modul utama aplikasi, yang antara lain, menentukan kata laluan pentadbir:

@Module public class AppModule { @Provides public SignatureKey signatureKey() { return new SignatureKey("restx-demo -44749418370 restx-demo 801f-4116-48f2-906b" .getBytes(Charsets.UTF_8)); } @Provides @Named("restx.admin.password") public String restxAdminPassword() { return "1234"; } @Provides public ConfigSupplier appConfigSupplier(ConfigLoader configLoader) { return configLoader.fromResource("restx/demo/settings"); } // other provider methods to create components }

@Module mendefinisikan kelas yang dapat menentukan komponen lain, serupa dengan @Module di Dagger, atau @Configuration pada Spring.

@Provides memperlihatkan komponen secara terprogram, seperti @Provides in Dagger, atau @Bean pada Spring.

Dan akhirnya, anotasi @Nama digunakan untuk menunjukkan nama komponen yang dihasilkan.

AppModule juga menyediakan SignatureKey yang digunakan untuk menandatangani kandungan yang dihantar kepada pelanggan. Semasa membuat sesi untuk aplikasi sampel, misalnya, ini akan menetapkan kuki, ditandatangani dengan kunci yang dikonfigurasi:

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

Dan periksa dokumentasi suntikan kilang / pergantungan komponen RESTX untuk lebih banyak lagi.

8. Kelas Pelancar

Dan terakhir, kelas AppServer digunakan untuk menjalankan aplikasi sebagai aplikasi Java standard di pelayan Jetty yang disematkan:

public class AppServer { public static final String WEB_INF_LOCATION = "src/main/webapp/WEB-INF/web.xml"; public static final String WEB_APP_LOCATION = "src/main/webapp"; public static void main(String[] args) throws Exception { int port = Integer.valueOf(Optional.fromNullable(System.getenv("PORT")).or("8080")); WebServer server = new Jetty8WebServer(WEB_INF_LOCATION, WEB_APP_LOCATION, port, "0.0.0.0"); System.setProperty("restx.mode", System.getProperty("restx.mode", "dev")); System.setProperty("restx.app.package", "restx.demo"); server.startAndAwait(); } }

Di sini, mod dev digunakan semasa fasa pengembangan untuk membolehkan ciri seperti auto-compile yang memendekkan loop maklum balas pembangunan.

Kami dapat mengemas aplikasi sebagai fail perang (arkib web) untuk digunakan dalam wadah web J2EE yang berdiri sendiri.

Mari cari cara menguji aplikasi di bahagian seterusnya.

9. Ujian Integrasi Menggunakan Spesifikasi

Salah satu ciri kuat RESTX adalah konsep "spesifikasi". Satu sampel spec akan kelihatan seperti ini:

title: should admin say hello given: - time: 2013-08-28T01:18:00.822+02:00 wts: - when: | GET hello?who=xavier then: | {"message":"hello xavier, it's 01:18:00"}

The test is written in a Given-When-Then structure within a YAML file which basically defines how the API should respond (then) to a specific request (when) given a current state of the system (given).

The HelloResourceSpecTest class in src/test/resources will trigger the tests written in the specs above:

@RunWith(RestxSpecTestsRunner.class) @FindSpecsIn("specs/hello") public class HelloResourceSpecTest {}

The RestxSpecTestsRunner class is a custom JUnit runner. It contains custom JUnit rules to:

  • set up an embedded server
  • prepare the state of the system (as per the given section in the specs)
  • issue the specified requests, and
  • verify the expected responses

The @FindSpecsIn annotation points to the path of the spec files against which the tests should be run.

The spec helps to write integration tests and provide examples in the API docs. Specs are also useful to mock HTTP requests and record request/response pairs.

10. Manual Testing

We can also test manually over HTTP. We first need to log in, and to do this, we need to hash the admin password in the RESTX console:

hash md5 

And then we can pass that to the /sessions endpoint:

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

(Note that Windows users need to download curl first.)

And now, if we use the session as part of our /message request:

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

Then we'll get something like this:

{"message" : "hello admin, it's 09:56:51"}

11. Exploring the Admin Console

The admin console provides useful resources to control the app.

Let's take a look at the key features by browsing to //127.0.0.1:8080/admin/@/ui.

11.1. API Docs

The API docs section lists all available routes including all the options:

And we can click on individual routes and try them out on the console itself:

11.2. Monitoring

The JVM Metrics section shows the application metrics with active sessions, memory usage, and thread dump:

Under Application Metrics we have mainly two categories of elements monitored by default:

  • BUILD corresponds to the instantiation of the application components
  • HTTP corresponds to HTTP requests handled by RESTX

11.3. Stats

RESTX lets the user choose to collect and share anonymous stats on the application to give information to the RESTX community. We can easily opt out by excluding the restx-stats-admin module.

The stats report things like the underlying OS and the JVM version:

Because this page shows sensitive information,make sure to review its configuration options.

Apart from these, the admin console can also help us:

  • check the server logs (Logs)
  • view the errors encountered (Errors)
  • check the environment variables (Config)

12. Authorization

RESTX endpoints are secured by default. That means if for any endpoint:

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

When called without authentication will return a 401 by default.

To make an endpoint public, we need to use the @PermitAll annotation either at the method or class level:

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

Note that at the class level, all methods are public.

Further, the framework also allows specifying user roles using the @RolesAllowed annotation:

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

With this annotation, RESTX will verify if the authenticated user also has an admin role assigned. In case an authenticated user without admin roles tries to access the endpoint, the application will return a 403 instead of a 401.

By default, the user roles and credentials are stored on the filesystem, in separate files.

So, the user id with the encrypted password is stored under /data/credentials.json file:

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

Dan, peranan pengguna ditentukan dalam /data/users.json fail:

[ {"name":"user1", "roles": ["hello"]}, {"name":"user2", "roles": []} ]

Dalam aplikasi contoh, fail dimuat di AppModule melalui kelas FileBasedUserRepository :

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

The StdUser kelas memegang objek pengguna. Ia boleh menjadi kelas pengguna tersuai tetapi perlu disenaraikan menjadi JSON.

Kita tentu saja dapat menggunakan implementasi UserRepository yang berbeza , seperti yang terdapat di pangkalan data.

13. Kesimpulannya

Tutorial ini memberikan gambaran keseluruhan mengenai kerangka RESTX berbasis Java yang ringan.

Kerangka ini masih dalam pengembangan dan mungkin ada beberapa sisi kasar yang menggunakannya. Lihat dokumentasi rasmi untuk maklumat lebih lanjut.

Contoh aplikasi bootstrapped boleh didapati di repositori GitHub kami.