Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing documentation and enhance test coverage for getting-started-reactive-crud #1298

Open
wants to merge 1 commit into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions getting-started-reactive-crud/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Getting started with Quarkus

This is a CRUD service exposing endpoints over REST. These endpoints are used for get, add, update
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have a guide for that?

Because we usually avoid duplicating content in the quickstarts. Some of them have a README with a link to the guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to find it so I write at least what it's does. Now after some digging I found out that the guide was there in past but was changed by this PR . It seems that PR replace this quickstart by hibernate-reactive-panache-quickstart.

and
remove entries from database.

## Requirements

To compile and run this demo you will need:

- JDK 11+
- GraalVM
- httpie (or curl)

### Configuring GraalVM and JDK 11+

Make sure that both the `GRAALVM_HOME` and `JAVA_HOME` environment variables have been set, and that
a JDK 11+ `java` command is on the path.

See the [Building a Native Executable guide](https://quarkus.io/guides/building-native-image-guide)
for help setting up your environment.

## Building the application

Launch the Maven build on the checked out sources of this demo:

> ./mvnw package

### Running the demo

The Maven Quarkus plugin provides a development mode that supports live coding. To try this out:

> ./mvnw quarkus:dev

This command will leave Quarkus running in the foreground listening on port 8080.

Launch the second terminal which will be used to send a request.

To get list of all fruits visit [http://127.0.0.1:8080/fruits](http://127.0.0.1:8080/fruits) and all
fruit in database should be returned or you can use terminal and get all fruits by one of these
commands:
> http :8080/fruits
>
> curl 127.0.0.1:8080/fruits

The output of these command should display same content as browser.

You can also get fruit by id. In this example used id is equal to 1. Get fruit by id is
possible either by using browser or by terminal. To get fruit by browser
visit [http://127.0.0.1:8080/fruits/1](http://127.0.0.1:8080/fruits/1) and info about kiwi fruit
should be displayed. To get fruit by terminal:
> http :8080/fruits/1
>
> curl 127.0.0.1:8080/fruits/1

The output of these command should display same content as browser.

Next we add lemon fruit. To add fruit the POST request needs to be sent. This request must contain
key-value pair. In this case `name={fruitName}`. To add fruit send request from terminal:
> http POST :8080/fruits name=Lemon
>
> curl -X POST http://localhost:8080/fruits -H 'Content-Type: application/json' -d '{"name":"Lemon"}'

This request create fruit with name `Lemon`. Now you can check all fruits and the newly added fruit
should be visible.

To update name of fruit the PUT request needs to be sent. This request must contain two key-value
pairs. In this case `id={fruitId}` and `name={newFruitName}`. In this example used id is equal to 1.
To update fruit name send request from terminal:
> http PUT :8080/fruits/1 id=1 name=Pitaya
>
> curl -X PUT http://localhost:8080/fruits/1 -H "Content-Type: application/json" -d '{"id":1,
> "name":"Pitaya"}'

This request update name of fruit with index 1 to `Pitaya`. Now you can check all fruits and fruit
with index 1 should be updated.

Now as you know how to show, add and update fruits last step will be to delete fruit. To delete
fruit you need to know its id. In case of this example the fruit with id equal to 1 will be
deleted. To delete fruit the DELETE request needs to be sent. To delete fruit send request from
terminal:
> http DELETE :8080/fruits/1
>
> curl -X DELETE http://localhost:8080/fruits/1

Check that fruit with id 1 is not existing anymore.

### Run Quarkus in JVM mode

When you're done iterating in developer mode, you can run the application as a conventional jar
file.

First compile it:

> ./mvnw package

Then run it:

> java -jar ./target/quarkus-app/quarkus-run.jar

Have a look at how fast it boots, or measure the total native memory consumption.

### Run Quarkus as a native executable

You can also create a native executable from this application without making any source code
changes. A native executable removes the dependency on the JVM: everything needed to run the
application on the target platform is included in the executable, allowing the application to run
with minimal resource overhead.

Compiling a native executable takes a bit longer, as GraalVM performs additional steps to remove
unnecessary codepaths. Use the `native` profile to compile a native executable:

> ./mvnw package -Dnative

After getting a cup of coffee, you'll be able to run this executable directly:

> ./target/getting-started-reactive-rest-1.0.0-SNAPSHOT-runner
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.core.IsNot.not;

import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.TestMethodOrder;

@QuarkusTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class FruitResourceTest {
private static String newFruit = "Lemon";
private static String updatedFruit = "Pitaya";

@Test
public void testListAllFruits() {
@Order(1)
public void testAddFruit() {
//List all, should have all 4 fruits the database has initially:
given()
.when().get("/fruits")
Expand All @@ -24,22 +31,113 @@ public void testListAllFruits() {
containsString("Pomelo"),
containsString("Lychee"));

//Delete the Kiwi:
// Add new fruit
given()
.when().contentType("application/json")
.body("{\"name\":\"" + newFruit + "\"}")
.post("/fruits")
.then()
.statusCode(201);

//List all, should have 4 fruits the database has initially and 1 added fruit:
given()
.when().get("/fruits")
.then()
.statusCode(200)
.body(
containsString("Kiwi"),
containsString("Durian"),
containsString("Pomelo"),
containsString("Lychee"),
containsString(newFruit));
}

@Test
@Order(2)
public void testUpdateFruit() {
//List all, should have 4 fruits the database has initially and 1 added fruit:
given()
.when().get("/fruits")
.then()
.statusCode(200)
.body(
containsString("Kiwi"),
containsString("Durian"),
containsString("Pomelo"),
containsString("Lychee"),
containsString(newFruit));

// Update name of added fruit
given()
.when().contentType("application/json")
.body("{\"id\":5, \"name\":\"" + updatedFruit + "\"}")
.put("/fruits/5")
.then()
.statusCode(200);

//List all, should have 4 fruits the database has initially and 1 updated fruit:
given()
.when().get("/fruits")
.then()
.statusCode(200)
.body(
containsString("Kiwi"),
containsString("Durian"),
containsString("Pomelo"),
containsString("Lychee"),
containsString(updatedFruit));
}

@Test
@Order(3)
public void testListAllFruits() {
//List all, should have 5 fruits the database has initially:
given()
.when().get("/fruits")
.then()
.statusCode(200)
.body(
containsString("Kiwi"),
containsString("Durian"),
containsString("Pomelo"),
containsString("Lychee"),
containsString(updatedFruit));

//Delete the Pitaya:
given()
.when().delete("/fruits/1")
.when().delete("/fruits/5")
.then()
.statusCode(204);

//List all, Kiwi should be missing now:
//List all, Pitaya should be missing now:
given()
.when().get("/fruits")
.then()
.statusCode(200)
.body(
not(containsString("Kiwi")),
containsString("Kiwi"),
containsString("Durian"),
containsString("Pomelo"),
containsString("Lychee"));
containsString("Lychee"),
not(containsString(updatedFruit)));
}

@Test
public void testNotFoundForDelete() {
given()
.when().delete("/fruits/3939")
.then()
.statusCode(404);
}

@Test
public void testNotFoundForUpdate() {
given()
.when().contentType("application/json")
.body("{\"id\":3939, \"name\":\"" + updatedFruit + "\"}")
.put("/fruits/3939")
.then()
.statusCode(404);
}

}