Minborg

Minborg
Minborg
Showing posts with label Streams. Show all posts
Showing posts with label Streams. Show all posts

Wednesday, March 4, 2020

Java/Spring: How to Generate an Entire Swagger Documented CRUD REST API With Speedment

As developers, one of the most cumbersome tasks we often face in our day-to-day lives is writing good and understandable documentation. It doesn’t matter if our documentation is only a few lines long explaining the core functionality of a feature or if it’s a full-blown essay demonstrating the ins and outs of a system. What matters is that the message we’re trying to convey through our documentation is precise and understandable.

In our previous article, we covered the topic of automatic REST API generation. More precisely, we demonstrated how to generate an entire CRUD REST API for your database using Speedment’s revamped Spring Integration plugin.

Today, we’ll be taking this knowledge a step further and demonstrate how to generate interactive documentation for your REST API in a single click.

If you didn’t get a chance to use the Speedment Spring plugin, we highly suggest you read our previous article as it contains the information necessary to follow this guide.

Do You Like Java Streams?

If the answer to this question is either ‘Yes!’, ‘Absolutely!’ or perhaps ‘Heck yeah!’, then Speedment is the right tool for you. Speedment is a Java ORM toolkit and runtime which uses pure Java Streams as an interface between your application and the database.

Alongside the already familiar Streams API, Speedment provides end-users with a graphical tool in order to generate a Java representation of your database in a matter of seconds, allowing them to completely stay in a Java-only environment.

If you’re interested in learning more about Speedment, head over to the documentation page where you’ll find a bunch of guides and examples. For the remainder of this article, we’ll be focusing on the new update to Speedment’s Spring plugin.

Before we Begin

In order to generate the REST API documentation, Speedment uses a combination of the OpenAPI specification and Swagger UI.

The preparation steps will differ depending on if you’re starting from scratch or not, but the end result will be the same regardless of your starting point.

If you have followed the guide in our previous article, where we explain how to generate a REST API using Speedment, you’ll only need to add a couple of dependencies to your project’s pom.xml file:
 
<dependencies>
    ...
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>
   ...
</dependencies>

On the other hand, if you’re starting from scratch, head over to the Initializer where you’ll be able to generate a Speedment project with Spring support. Once you reach the Initializer, you’ll be presented with plenty of options to configure your project. One configuration option that is particularly important is the Plugins section of the Initializer.

To enable Spring support in your new Speedment project, tick the checkbox next to the "Spring" option. Once you’re happy with your project configuration, go ahead and click the Download button at the bottom of the Initializer.



When you’re ready, you can launch the Speedment Tool by executing the following command from the root folder of your project template:

mvn speedment:tool

If you’ve installed the plugin correctly, you’ll see some Spring Boot specific options which can be used to configure your REST API and documentation.

If this is your first time using Speedment, you may want to familiarize yourself with the workflow by following the “Hello Speedment” quick start guide.

Swagger Automata

For the following example, we’ll be using Sakila, a MySQL Sample Database. You can download it as a standalone instance or as a Docker container.

When you open the Speedment Tool and successfully connect to your database, you will be presented with a user interface containing the metadata information about your database and some options that you can configure:



If you click the “Generate” button found in the top banner, a Java representation of your database will get generated. To generate the documentation for your REST API, you must enable the “Generate REST documentation” option found in the project view (which is accessed by selecting the top node in the tree).

Once enabled, additional configuration options will become available allowing you to further customize your generated documentation:



The next time you regenerate your Spring project, some OpenAPI specific configurations will get generated. In order to see and use the generated documentation, you’ll need to run your Spring application. To do so, execute the following command:
 
mvn spring-boot:run


Once your Spring application is up and running, you can find your generated Swagger documentation at the following endpoint - http://localhost:8080/swagger-ui.html



Depending on how you configured your project, you might see different results in the generated documentation. For instance, if you disable REST API generation for a certain table, the next time you regenerate your project, the endpoint for that table will not be available in the documentation.

With the generated Swagger documentation, you’re able to instantly learn what REST endpoints your application has registered, what HTTP methods are available for each endpoint and execute HTTP requests for those endpoints directly from the Swagger UI:



If you’re not sure what is required in the request body, you can find the request body models at the bottom of the documentation, under the “Models” section:



Note: When connecting to the Swagger endpoint, if you get presented with the following prompt, make sure your Spring entry point is in the correct package (must be above or in the same package that the Swagger configuration is located in):



This is usually a sign that your Swagger configuration was not scanned by Spring.

Summary

Writing good and understandable documentation can be a long and tedious process. With the new update to Speedment’s Spring Boot plugin, users are able to generate interactive documentation for their REST API in a matter of seconds.

Resources

Article "How to Generate an Entire Database CRUD REST API with Speedment"
The Speedment Initializer capable of generating project templates
Speedment on GitHub

Authors

Per Minborg
Mislav Miličević

Friday, October 4, 2019

Become a Master of Java Streams - Part 1: Creating Streams

Declarative code (e.g. functional composition with Streams) provides superior code metrics in many cases. Code your way through this hands-on-lab article series and mature into a better Java programmer by becoming a Master of Java Streams.

The whole idea with Streams is to represent a pipeline through which data will flow and the pipeline’s functions operate on the data. This way, functional-style operations on Streams of elements can be expressed. This article is the first out of five where you will learn firsthand how to become a Master of Streams. We start with basic stream examples and progress with more complex tasks until you know how to connect standard Java Streams to databases in the Cloud.

Once you have completed all five articles, you will be able to drastically reduce your codebase and know how to write pure Java code for the entire applications in a blink.

Here is a summary of the upcoming articles:


Since we are firm believers in the concept of ”Learning by doing”, the series is complemented by a GitHub repository that contains Stream exercises split into 5 Units - each corresponding to the topic of an article. Instructions on how to use the source code are provided in the README-file.

What are Java Streams?

The Java Stream interface was first introduced in Java 8 and, together with lambdas, acts as a milestone in the development of Java since it contributes greatly to facilitating a declarative (functional) programming style. If you want to learn more about the advantages of declarative coding we refer you to this article.

A Java Stream can be visualized as a pipeline through which data will flow (see the image below). The pipeline’s functions will operate on the data by e.g. filtering, mapping and sorting the items. Lastly, a terminal operation can be performed to collect the items in a preferred data structure such as a List, an Array or a Map. An important thing to notice is that a Stream can only be consumed once.


A Stream Pipeline contains three main parts; the stream source, the intermediate operation(s) (zero to many) and a terminal operation.

Let’s have a look at an example to get a glimpse of what we will be teaching throughout this series. We encourage you to look at the code below and try to figure out what the print-statement will result in before reading the next paragraph.

List<String> list = Stream.of("Monkey", "Lion", "Giraffe","Lemur")
    .filter(s -&gt; s.startsWith("L"))
    .map(String::toUpperCase)
    .sorted()
    .collect(toList());
System.out.println(list);

Since the Stream API is descriptive and most often intuitive to use, you will probably have a pretty good understanding of the meaning of these operations regardless if you have encountered them before or not. We start off with a Stream of a List containing four Strings, each representing an African animal. The operations then filter out the elements that start with the letter “L”, converts the remaining elements to uppercase letters, sorts them in natural order (which in this case means alphabetical order) and lastly collects them into a List. Hence, resulting in the output [“LEMUR”, “LION”].

It is important to understand that Streams are “lazy” in the sense that elements are “requested” by the terminal operation (in this case the .collect() statement). If the terminal operation only needs one element (like, for example, the terminal operation .findFirst()), then at most one element is ever going to reach the terminal operation and the reminding elements (if any) will never be produced by the source. This also means that just creating a Stream is often a cheap operation whereas consuming it might be expensive depending on the stream pipeline and the number of potential elements in the stream.

In this case, the Stream Source was a List although many other types can act as a data source. We will spend the rest of this article describing some of the most useful source alternatives.


Stream Sources

Streams are mainly suited for handling collections of objects and can operate on elements of any type T. Although, there exist three special Stream implementations; IntStream, LongStream, and DoubleStream which are restricted to handle the corresponding primitive types.

An empty Stream of any of these types can be generated by calling Stream.empty() in the following manner:

Stream<T>     Stream.empty()
IntStream     IntStream.empty()
LongStream    LongStream.empty()
DoubleStream  DoubleStream.empty()

Empty Streams are indeed handy in some cases, but the majority of the time we are interested in filling our Stream with elements. This can be accomplished in a large number of ways. We will start by looking at the special case of an IntStream since it provides a variety of useful methods.


Useful IntStreams

A basic case is generating a Stream over a small number of items. This can be accomplished by listing the integers using IntStream.of(). The code below yields a simple stream of elements 1, 2 and 3.
IntStream oneTwoThree = IntStream.of(1, 2, 3);
Listing all elements manually can be tedious if the number of items grows large. In the case where we are interested in values in a certain range, the command .rangeClosed() is more effective. The operation is inclusive, meaning that the following code will produce a stream of all elements from 1 to 9.
IntStream positiveSingleDigits = IntStream.rangeClosed(1, 9);

An even more powerful command is .iterate() which enables greater flexibility in terms of what numbers to include. Below, we show an example of how it can be used to produce a Stream of all numbers that are powers of two.
IntStream powersOfTwo = IntStream.iterate(1, i -> i * 2);
There are also several perhaps more unexpected ways of producing a Stream. The method chars() can be used to Stream over the characters in a String, in this case, the elements “A”, “B” and “C”.
IntStream chars = "ABC".chars();
There is also a simple way to generate a Stream of random integers.
IntStream randomInts = new Random().ints();

Stream an Array

Streaming existing data collections is another option. We can stream the elements of an existing Array or choose to list items manually using Stream.of() as previously shown and repeated below.
String[] array = {"Monkey", "Lion", "Giraffe", "Lemur"};
Stream<String> stream2 = Stream.of(array);
Stream<String> stream = Stream.of("Monkey", "Lion", "Giraffe", "Lemur");

Stream from a Collection

It is also very simple to stream any Collection. The examples below demonstrate how a List or Set can be streamed with the simple command .stream().
List<String> list = Arrays.asList("Monkey", "Lion", "Giraffe", "Lemur");
Stream<String> streamFromList = list.stream();
Set<String> set = new HashSet<>(list);
Stream<String> streamFromSet = set.stream();

Stream from a Text File

Sometimes it can also be useful to stream the contents of a text-file. The following command will provide a Stream<String> that holds every line from the referenced file as a separate element.

Stream<String> lines = Files.lines(Paths.get("file.txt"));


Exercise

Now that we have familiarized you with some of the ways of creating a Stream, we encourage you to clone this GitHub repo and start practicing. The content of the article will be enough to solve the first Unit which is called Create. The Unit1Create interface contains JavaDocs which describes the intended implementation of the methods in Unit1MyCreate.
public interface Unit1Create {
 /**
  * Creates a new Stream of String objects that contains
  * the elements "A", "B" and "C" in order.
  *
  * @return a new Stream of String objects that contains
  *   the elements "A", "B" and "C" in order
  */
  Stream<String> newStreamOfAToC();
The provided tests (e.g. Unit1MyCreateTest) will act as an automatic grading tool, letting you know if you solution was correct or not.


If you have not done so yet, go ahead and solve the work items in the Unit1MyCreate class. “Gotta catch ‘em all”.

In the next article, we will continue to describe several intermediate operations that can be applied to these Streams and that will convert them into other Streams. See you soon!

Authors 

Per Minborg
Julia Gustafsson

Wednesday, December 21, 2016

Day 21, Java Holiday Calendar 2016, Concatenate Java Streams

Day 21, Java Holiday Calendar 2016, Concatenate Java Streams




Today's tip is about concatenating streams. The task of the day is to construct a concatenated stream that lazily consumes a number of underlying streams. So, dumping the content from the various streams into a List and then stream from the list or using the Stream.builder() will not do.

As an example, we have three streams with words that are relevant to the US history and constitution:

        // From 1787
        final Stream preamble = Stream.of(
            "We", "the", "people", "of", "the", "United", "States"
        );

        // From 1789
        final Stream firstAmendment = Stream.of(
            "Congress", "shall", "make", "no", "law", 
            "respecting", "an", "establishment", "of", "religion"
        );

        // From more recent days
        final Stream epilogue = Stream.of(
            "In", "reason", "we", "trust"
        );


Creating a concatenated stream can be done in many ways including these:

        // Works for a small number of streams
        Stream.concat(
            preamble,
            Stream.concat(firstAmendment, epilogue)
        )
            .forEach(System.out::println);

        
        // Works for any number of streams
        Stream.of(preamble, firstAmendment, epilogue)
            .flatMap(Function.identity())
            .forEach(System.out::println);


Both methods will produce the same result and they will also close the underlying streams upon completion. Personally, I prefer the latter method since it is more general and can concatenate any number of streams. This is the output of the program:

We
the
people
of
the
United
States
Congress
shall
make
no
law
respecting
an
establishment
of
religion
In
reason
we
trust

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season. I am contributing to open-source Speedment, a stream based ORM tool and runtime. Please check it out on GitHub.

Sunday, December 18, 2016

Day 18, Java Holiday Calendar 2016, Easily Create Database Content


Day 18, Easily Create Database Content




Today's tips is about creating database content. There are a number of ways to do this, ranging from writing our own entity beans combined with using JDBC directly to fully automating the entire process.

Suppose we already have a database table like this:

mysql> explain country
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| name       | varchar(45) | YES  | UNI | NULL    |                |
| local_name | varchar(45) | YES  |     | NULL    |                |
| code       | int(11)     | YES  |     | NULL    |                |
| domain     | varchar(10) | YES  |     | NULL    |                
+------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

Then we could add the Speedment plugin and dependency to our POM and launch the Speedment graphic tool that will analyze the database and generate code automatically for us.

After generation we can do this:

Initialization:

final MyApplication app = new MyApplicationBuilder()
    .withPassword("myPwd729") // Replace with the real pwd
    .build();

final CountryManager countries = app.getOrThrow(CountryManager.class);

Insert DB Content:

countries.persist(
    new CountryImpl()
        .setName("Sweden")
        .setLocalName("Sverige")
        .setCode(40)       // Intentionally wrong, should be 46!!
        .setDomain(".se")
);

Update DB Content:

countries.stream()
    .filter(Country.NAME.equal("Sweden"))  // Filter out Sweden
    .map(c -> c.setCode(46))               // Update code to 46
    .forEach(countries.updater());         // Apply the database updater

Read more on Speedment on GitHub here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season. I am contributing to open-source Speedment, a stream based ORM tool and runtime. Please check it out on GitHub.

Tuesday, December 13, 2016

Day 13, Java Holiday Calendar 2016, Try Higher Order of Functionality

13. Higher Order of Functionality



Today's tips is to explore the world of Higher Order Functionality and how to work with functions that operates on functions.

In the good old pre-Java 8 days, algorithms mostly operated on data structures. But with the introduction of  functions in Java 8, our programs may now also reason about behavior. Programming a program that operates on other programs opens up a whole new level of abstractions which allows for elegant declarative programs that express what to be done rather than how, leaving the details about the execution to a framework that performs the operation from "what" to "how" as a higher order operation.

We could, for example, write a QuickSort algorithm that may sort anything (that extends Object) stored anyhow by just providing functional parameters in the form of a getter,  a comparer, a swapper and the number of elements to sort. This enables the QuickSort algorithm to sort lists, arrays or even serialized off heap objects using the same basic algorithm. The QuickSort algorithm just applies the provided functions agnostically. Thus, we only need to write QuickSort once and then we can re-use it by just providing the appropriate functions.

Speedment is an Open Source ORM with an API founded on Java 8 streams. With Speedment you can apply functions that takes functions as a parameter. For example you can:

users.stream()
  .filter(User.BORN.between(1985, 1995)) // Filters out Users born 1985 up to and including 1994
  .map(User.CATEGORY.setTo(3))           // Applies a function that sets their category to 3
  .forEach(users.updater());             // Applies the updater function to the selected users

The code snippet above will;

a) extract users from an underlying database where the users are born between 1985 and 1995 (and only those users)
b) for each such user, it will apply a mapping from a user to an updated user where the category has been set to 3 (but all other fields remain the same)
c) for each updated user, a database updater method will be applied that will result in the updated user being persisted in the database.

So, the snippet above is a sequence of methods that are provided other methods as per the paradigm of Higher Order of Functionality. If we later elect to store our data not in a database but in a file, in memory or even in an Excel diagram, then we only need to provide another set of functions. The stream logic will remain exactly the same.


Read more on Higher Order of Functionality here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Saturday, December 10, 2016

Day 10, Java Holiday Calendar 2016, MapStream

Day 10, Java Holiday Calendar 2016, MapStream



Today's tips is about the open-source class MapStream that allows us to stream not only over elements but over pair of key, value elements and make changes either to the keys, values or both.

You can find the source code for MapStream here together with some examples of how to use it. It is free so go ahead and use or copy it in your application! MapStream is a part of open-source Speedment, a stream ORM tool and runtime.

With MapStream you can do this:

Map<String, Integer> numberOfCats = new HashMap<>();

numberOfCats.put("Anne", 3);
numberOfCats.put("Berty", 1);
numberOfCats.put("Cecilia", 1);
numberOfCats.put("Denny", 0);
numberOfCats.put("Erica", 0);
numberOfCats.put("Fiona", 2);

System.out.println(
  MapStream.of(numberOfCats)
      .filterValue(v -> v > 0)
      .sortedByValue(Integer::compareTo)
      .mapKey(k -> k + " has ")
      .mapValue(v -> v + (v == 1 ? " cat." : " cats."))
      .map((k, v) -> k + v)
      .collect(Collectors.joining("\n"))
);

This would produce the following:

Cecilia has 1 cat.
Berty has 1 cat.
Fiona has 2 cats.
Anne has 3 cats.

Learn more on MapStream here.

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.




Monday, April 11, 2016

Java 8: Use Smart Streams with Your Database in 2 Minutes

Streaming with Speedment

Duke and Spire Mapping Streams.

Back in the ancient 90s, we Java developers had to struggle with making our database application work properly. There was a lot of coding, debugging and tweaking. Still, the applications often blew up right in our faces to our ever increasing agony. Things gradually improved over time with better language, JDBC and framework support. I'd like to think that we developers also improved, but there are different opinions on that...

When Java 8 finally arrived, some colleges and I started an open-source project to take the whole Java/DB issue one step further by leveraging on Java 8's stream library, so that database tables could be viewed as pure Java 8 streams. Speedment was born! Wow, now we can do type-safe database applications without having to write SQL-code any more.

Speedment connects to existing databases and generate Java code. We can then use the generated code to conveniently query the database using standard Java 8 streams. With the new version 2.3 hitting the shelves just recently, we can even do parallel query streams!

Let's take some examples assuming we have the following database table defined:
 
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  `firstName` varchar(45) DEFAULT NULL,
  `lastName` varchar(45) DEFAULT NULL,
  `email` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`),
  UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB;

Speedment is free for the open-source databases MySQL, PostgreSQL and MariaDB. There is also support for commercial databases, like Oracle, as an enterprise add-on feature.

Examples


Querying

Select all users with a ".com" mail address and print them:
        users.stream()
            .filter(EMAIL.endsWith(".com"))
            .forEach(System.out::println);
Select users where the first name is either "Adam" or "Cecilia" and sort them in username order, then take the first 10 of those and extract the email address and print it.
        users.stream()
            .filter(FIRST_NAME.in("Adam", "Cecilia"))
            .sorted(USERNAME.comparator())
            .limit(10)
            .map(User::getEmail)
            .forEach(System.out::println);

Creating Database Content

Create a new user and persist it in the database:
        users.newEmptyEntity()
            .setUsername("thorshammer")
            .setEmail("mastergamer@castle.com")
            .setPassword("uE8%3KwB0!")
            .persist();

Updating Database Content

Find the user with id = 10 and update the password:
        users.stream()
            .filter(ID.equal(10))
            .map(u -> u.setPassword("pA6#nLaX1Z"))
            .forEach(User::update); 

Removing Database Content

Remove the user with id = 100:
        users.stream()
            .filter(ID.equal(100))
            .forEach(User::remove);

New Cool Stuff: Parallel Queries

Do some kind of expensive operation in parallel for users with 10_000 <= id < 20_000
        users.stream()
            .parallel()
            .filter(ID.between(10_000, 20_000))
            .forEach(expensiveOperation());

Setup

Setup code for the examples above:
       final Speedment speedment = new JavapotApplication()
            .withPassword("javapot") // Replace with your real DB password
            .build();

        final Manager<User> users = speedment.managerOf(User.class);

Get Started with Speedment


Read more here on GitHub on how to get started with Speedment.

Read more about the complete set of Java 8 features including Streams.



Wednesday, November 5, 2014

Compute factorials using Java 8 streams


Background

N factorial (also denoted N!) means computing 1*2*3*...*N and is a classical problem used in computer science to illustrate different programming patterns. In this post I will show how one can use Java 8's Streams to calculate factorials. But first, I will show two other ways that were previously used before Java 8 appeared.

Recursion

From our computer science classes, we all remember the classical way of computing factorial(). The following method illustrates the concept:
    public long factorial(int n) {
        if (n > 20) throw new IllegalArgumentException(n + " is out of range");
        return (1 > n) ? 1 : n * factorial(n - 1);
    }
Because long overflows for n > 20, we need to throw an exception to avoid faulty return values. If we are within the valid input range, we check for the basic case where n is 1 or less for which factorial is 1, otherwise we recurse by returning n multiplied with factorial(n-1). Eventually, we will reach factorial(1) and the recursion stops.

Imperative 

You can also use the standard imperative way of doing it using an intermediate value that is used in a loop, like this:
    public long factorial(int n) {
        if (n > 20) throw new IllegalArgumentException(n + " is out of range");
        long product = 1;
        for (int i = 2; i < n; i++) {
            product *= i;
        }
        return product;
    }

Look at the loop and you might be surprised to see that we start from 2. We could as well have started from 1, but then again, multiplying with 1 always gives back the same result, doesn't it? So we optimize away that case.

Streams

Using Java 8's stream methods we can implement factorial() in another way as depicted here:
    public long factorial(int n) {
        if (n > 20) throw new IllegalArgumentException(n + " is out of range");
        return LongStream.rangeClosed(2, n).reduce(1, (a, b) -> a * b);
    }
Using the LongStream.rangeClosed(2, n) method we create a Stream of longs with the content 2, 3, ... , n. Then we take this Stream and successively applies the reduction (a, b) -> a * b meaning that for each pair a and b we multiply them and return the result. The result then carries over to a for the next round. The value "1" used in the reduced method is the identity value, i.e. the value that is used as a starting value for a for the first iteration.

This way, we abstract away the implementation and instead focus on what to do. For example, the Stream could be made parallel and that way we could calculate the value using several threads.  Perhaps not so useful in this particular example where n < 20, but certainly for other applications with longer iteration chains.

Consider using Streams when iterating over values!