WildFly Swarm REST example

Microservices are here. They have been here for a long time now and it looks like they are going to be here for a while. Some technologies have born in recent years to help developers to implement their systems following this architectural style. One of these technologies is WildFly Swarm.

Probably, if you are familiar with the Java EE world, you know the WildFly application server. WildFly Swarm is a derivate of this application server but it has been created with microservices architectural style in mind. Taking the definition from the WildFly Sward documentation page:

WildFly Swarm is a project that has taken the WildFly Java Application Server and deconstructed it into fine-grained parts. WildFly Swarm then allows the selective reconstitution of those parts back together with your application to allow building self-contained executable “uberjars”.

It has some other components and functions but, mainly, reading the definition we can understand the concept.

As I have said this technology is here to fill the gap that the old and big application servers cannot cover (This is a huge discussion) in the microservises world. It is comparable with Spring Boot or Payara Micro. With its different flavors and features, all of them cover the same gap.

One of the things that it calls our attention in the definition is the word “uberjars“. Considered a buzzword or maybe not, it is just defining a JAR file that contains a package and all its dependencies. In this case, for example, it is going to be a package that it is going to contain our code plus all the dependencies to run a server with our application just executing the order “java -jar file.jar” in a command line prompt.

After this little explanation, let’s go to build our first WildFly Swarm application. It is going to be a very simple REST application just with a method returning some text. And it is going to look like basically as a tradicional Java EE application. One of the best things of migrating a Java EE 7 application to WildFly Swarm is that the code doesn’t change at all. We can take the old and monolithic code and run it as an uberjar just with a few modifications in the maven pom.xml file.

The first step is to define the correct pom.xml file. In this file we are going to include the proper dependencies to build our REST service and a plugin that it is going to allow us to create our uberjar and/or run our application.

...
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>bom</artifactId>
            <version>${version.wildfly.swarm}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    ...
    <!-- Wildfly Swarm Fractions -->
    <dependency>
        <groupId>org.wildfly.swarm</groupId>
        <artifactId>jaxrs</artifactId>
    </dependency>		
</dependencies>

<build>
    <finalName>RestWildFlySwarm</finalName>
    <plugins>
        <plugin>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>wildfly-swarm-plugin</artifactId>
            <version>${version.wildfly.swarm}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>package</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

The second thing, it is just add the necessary code to the project to implement the REST service. Like I have said before, it is simple Java EE 7 code, I don’t think it need any especial explanation, if you need some additional explanation you have in this blog some articles about REST services and how to implement them in Java EE 7. One of this examples can be found here.

package com.example.rest;

import javax.ws.rs.core.Application;
import javax.ws.rs.ApplicationPath;

@ApplicationPath("/rest")
public class RestApplication extends Application {
}
package com.example.rest;

import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;

@Path("/messages")
@Produces(MediaType.APPLICATION_JSON)
public class MessagesEndPoint {

  @GET
  public Response getMessage() {
    return Response.ok("This is our first WildFly Swarm App. Awesome!").build();
  }
}

And that’s all we need to add to our first project. Now, we just need to run it.

The first way to do this, it is just running a simple maven command:

mvn wildfly-swarm:run

This first time is going to download a big bunch of dependencies and stuff, and it is going to take some time. Future executions will be much faster.

The second way to execute our application is creating our uberjar file and running it from the console.

mvn package
java -jar RestWildFlySwarm-swarm.jar

You can see the full code for the example here.

See you.

Advertisements
WildFly Swarm REST example

Java REST API + cURL + python3

During the next lines, I am going to implement a very simple REST API using JavaEE 7 and Java SE 8 technologies, maven as build tool and GlassFish as application server. I am going to test this API with cURL and, I am going to consume this API using python3 using the Requests module.

Java EE 7 REST API

First, we need to create a maven project in our favorite IDE and add our dependencies to the pom.xml file

...
<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <failOnMissingWebXml>false</failOnMissingWebXml>
</properties>

<dependencies>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>org.eclipse.persistence.jpa.modelgen.processor</artifactId>
        <version>2.5.2</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-api</artifactId>
        <version>7.0</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <finalName>apicrud</finalName>
</build>
...

Second, we are going to create a persistence.xml file. In this case, we are not interested in how to configure a DB, then, we are going to use the default datasource that GlassFish provides us as default “jdbc/__default“. With all of this in mind, the file should look like this:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="ApiCrudPU" transaction-type="JTA">
        <jta-data-source>jdbc/__default</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="create"/>
        </properties>
    </persistence-unit>
</persistence>

Now, we need to create our Entity. In this case, I have chosen a simple one, User with three attributes:

  • id: Autogenerated id to identify the user.
  • name: User’s name.
  • email: User’s email.

The result should be something like:

package com.wordpress.binarycoders.apicrud;

import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@Entity
@Table (name = "users")
@NamedQueries ({
    @NamedQuery (name = User.FIND_ALL, query = "SELECT u FROM User u")
})
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    public static final String FIND_ALL = "User.findAll";
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "email")
    private String email;

    /* Getters, Setters, equals and hashCode methods */    
}

The next step, it is to implement the boundary or service layer. Being a simple example, we can skip this layer, but I like to implement everything for learning purposes. This layer is going to be very simple, only the necessary object to perform the operation in the DB and the basic operations to implement a CRUD. The result looks like:

package com.wordpress.binarycoders.apicrud;

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.validation.constraints.NotNull;

@Stateless
public class UserService {
    
    @PersistenceContext
    private EntityManager em;
    
    public void create(@NotNull User user) {
        this.em.persist(user);
    }
    
    public User findById(@NotNull Long id) {
        return this.em.find(User.class, id);
    }
    
    public List<User> findAll() {
        TypedQuery<User> typedQuery = this.em.createNamedQuery(User.FIND_ALL, User.class);

        return typedQuery.getResultList();
    }
    
    public void update(@NotNull User user) {
        this.em.merge(user);
    }
    
    public void delete(@NotNull Long id) {
        this.em.remove(this.findById(id));
    }
}

To do all of this available to the world, we need to implement our REST API, and for this, we need to configure the REST capabilities in our system, piece of cake with the last version of Java EE. We just need to create a class to enable these capabilities:

package com.wordpress.binarycoders.apicrud;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/rs")
public class ApplicationConfig extends Application {
    
}

And, finally, we need to implement our REST layer with the four actions that are going to allow us to perform the CRUD operations:

package com.wordpress.binarycoders.apicrud;

import java.net.URI;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("/users")
@Produces ({ MediaType.APPLICATION_JSON })
@Consumes ({ MediaType.APPLICATION_JSON })
@Stateless
public class UserEndPoint {
    
    @EJB
    private UserService service;
    
    @Context
    private UriInfo uriInfo;
    
    @GET
    public Response findAll() {
        List<User> users = this.service.findAll();
        
        GenericEntity<List<User>> list = new GenericEntity<List<User>>(users) {};
        
        return Response.ok(list).build();
    }
    
    @GET
    @Path("/{id}")
    public Response findById(@PathParam("id") Long id) {
        User user = this.service.findById(id);
        
        if (user == null) {
            throw new NotFoundException();
        }
        
        return Response.ok(user).build();
    }
    
    @POST
    public Response create(User user) {
        this.service.create(user);
        
        URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build();
        
        return Response.created(uri).build();
    }
    
    @PUT
    public Response update(User user) {
        this.service.update(user);
        
        return Response.ok().build();
    }
    
    @DELETE
    @Path("/{id}")
    public Response delete(@PathParam("id") Long id) {
        this.service.delete(id);
        
        return Response.noContent().build();
    }
}

I think that in this point, assuming that everyone reading this, it is a developer and this is not an entry level post, all of you should be capable to understand everything has been written in the above lines. If there are things that you do not know or you do not understand due to a lack of information or your knowledge is not enough (all of us have been there), look at the note at the end of this post.

cURL test

Now, obviously, we need to test if our REST API is working properly. For this, we can implement some solution based on test frameworks or manual code but, due to the simplicity of the object User, it is enough with the cURL tool. To test our API we are going to perform these operations:

  • Select all the users
  • Create a user
  • Select the created user
  • Update the user
  • Delete the user

These operations can be performed with the next commands:

curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X POST -d '{"name":"john","email":"john@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" http://localhost:8080/ApiCRUD/rs/users/1
curl -i -H "Content-Type: application/json" -X PUT -d '{"id”:1,”name":"John Doe","email":"john.doe@example.org"}' http://localhost:8080/ApiCRUD/rs/users
curl -i -H "Content-Type: application/json" -X DELETE http://localhost:8080/ApiCRUD/rs/users/1

Everything should look well, and the appropriate HTTP codes should be received.

Python3 client

The last step today, it is to implement a very very simple python3 client to consume our API. This is going to be a basic script to invoke the CRUD operations available in the API.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import json

URL = 'http://localhost:8080/ApiCRUD/rs/users'

def getUsers():
	print('Get users...\n')

	response = requests.get(URL)

	assert response.status_code == 200

	users = response.json()
	print(json.dumps(users, indent = 4, separators = (',', ':')))

def getUser(location):
	print('Get single user ...\n')

	response = requests.get(location)

	assert response.status_code == 200

	users = response.json()
	print(json.dumps(users, indent = 4, separators = (',', ':')))

def createUser():
	print('Creating user...\n')

	headers = {'content-type': 'application/json'}
	user = {"name": "John Doe", "email": "john.doe@example.org"}
	response = requests.post(URL, data = json.dumps(user), headers = headers)

	assert response.status_code == 201

	print('Location: ' + response.headers['location'])

	return response.headers['location']

def updateUser(location):
	print('Updating user...')

	loc = location.split('/')

	headers = {'content-type': 'application/json'}
	user = {"id": loc[-1], "name": "Jane Doe", "email": "jane.doe@example.org"}
	response = requests.put(URL, data = json.dumps(user), headers = headers)

	assert response.status_code == 200

def deleteUser(location):
	print('Deleting user...')

	response = requests.delete(location)

	assert response.status_code == 204

	print('Checking delete operation')
	response = requests.get(location)

	assert response.status_code == 404

def main():
	getUsers()
	location = createUser()
	getUser(location)
	updateUser(location)
	getUser(location)
	deleteUser(location)

if __name__ == "__main__":
	main()

And that’s all. Now, we have a little REST AP, a python3 client and a basic knowledge about how to use cURL to test it.

See you.

You can find the code for the REST API available here.

Note: All the content in this post will be splitter and explained in future post, one for each one of the three big point explained in here: Java EE 7 REST API creation, cURL test and python3 REST client.

Java REST API + cURL + python3

Quick REST demo with Spark

What is Spark? If we take a look to the project’s web page, it says something like “Spark is a simple and lightweight Java web framework built for rapid development“. In other words, it proposes us a simple way to build web applications without dealing with XML or annotations.

I recognize I do not usually use it but I have found it very useful when I need to prepare some REST services for a quick demo. Do not missunderstanding me, I think that use the Java EE platform is amazing and you can develop with it very fast, but you need a server, a couple of classes with the JAX-RS configuration and a few annotations to make everything work. With Spark, you only need to add a dependency in you .pom file and write a few lines of code.

For the example, I am going to implement a little application offering REST services with the CRUD operations for a User. This entity is going to have:

  • id
  • name
  • surname

In first place, we should create a java application in our favorite IDE using maven.

In second place, we are going to add the correct maven dependency for the Spark library.

<dependencies>
	<dependency>
		<groupId>com.sparkjava</groupId>
		<artifactId>spark-core</artifactId>
		<version>2.1</version>
	</dependency>
</dependencies>

In third place, we should create our entity object.

public class User {
	private String id;
	private String name;
	private String surname;
	
	// Getters and setters
}

Now, we need to start to write our main class. In this main class we are going to add a couple of things:

  • A Map to simulate our data store.
  • A main method that it is going to contain our REST services.

The main class looks like:

public class Users {
	private static Map<String, User> users = new HashMap<String, User>();

	public static void main(String[] args) {
		final Random random = new Random();
		
		// Services here
	}
}

Now, we are going to start with the services.

/users?name=Foo&surname=Bar (POST)

Spark.post("/users", (request, response) -> {
	String name = request.queryParams("name");
	String surname = request.queryParams("surname");

	User user = new User(name, surname);
	int id = random.nextInt(Integer.MAX_VALUE);
	
	users.put(String.valueOf(id), user);

	response.status(201); // 201 Created
	
	return id;
});

/users/:id (GET)

Spark.get("/users/:id", (request, response) -> {
	User user = users.get(request.params(":id"));
	if (user != null) {
		return "Name: " + user.getName() + ", Surname: " + user.getSurname();
	} else {
		response.status(404); // 404 Not found
		return "User not found.";
	}
});

/users/:id (PUT)

Spark.put("/users/:id", (request, response) -> {
	String id = request.params(":id");
	User user = users.get(id);
	if (user != null) {
		String newName = request.queryParams("name");
		String newSurname = request.queryParams("surname");
		if (newName != null) {
			user.setName(newName);
		}
		if (newSurname != null) {
			user.setSurname(newSurname);
		}
		return "User with id '" + id + "' has been updated.";
	} else {
		response.status(404); // 404 Not found
		return "User not found.";
	}
});

/users/:id (DELETE)

Spark.delete("/users/:id", (request, response) -> {
	String id = request.params(":id");

	User user = users.remove(id);

	if (user != null) {
		return "User with id '" + id + "'has been deleted";
	} else {
		response.status(404); // 404 Not found
		return "User not found.";
	}
});

/users (GET)

Spark.get("/users", (request, response) -> {
	String ids = "";

	for (String id : users.keySet()) {
		ids += id + " ";
	}
	
	return ids;
});

Now, we only need to execute our application and check if everything is working correctly. To do this, we can use cURL or our browser with the URL:

http://localhost:4567/users

The next steps are on you. Implement a front-end with Javascript or consuming the services with a mobile app or… whatever you prefer.

See you.

Quick REST demo with Spark

Testing REST with cURL

Nowadays is very common for developers, especially for back-end developers, develop some REST services to be consumed by the front-end developers. At the end of the development cycle usually you have (or you should have) some beautiful test suits that allow you to test your services and check if everything is working well. But, what happen during the development? The developer usually needs to test the services punctually, needs to test the connectivity or needs to perform a few test to check the REST API that he is investigating or trying to consume. There are some different solution to do this, create a little application to do it, use one of the plugins for the different browsers to use REST services, or use cURL. In this post, I am going to explain how to use cURL to perform these little checks in a quick way.

If you do not know cURL, cURL is a command line tool and library for transferring data with URL syntax, supporting a lot of different formats and options. Usually, it is installed by default in Unix and Unix based systems. In windows systems you need to install it or if you are using Cygwin you probably have it installed.

The first step before to start to use cURL should be check if it is installed in our system and take a look to the manual or help information that the tool provide us.

Checking if cURL is install in our system:

curl

This command should returns us something like:

curl: try 'curl --help' or 'curl --manual' for more information

Now, we can read the information about the tool and how to use it, but this information is huge and for this reason I am going to explain below the options that we are going to need. To read the information about the tool we have some different options:

man curl
curl --help
curl --manual

After read all this documentation the main options that we are going to need to test a basic REST services implementing CRUD operations are:

  • i – shows response headers.
  • H – passes request headers to the resource.
  • X – passes the HTTP method name. Default option is GET.
  • d – passes in parameters enclosed in quotes; multiple parameters are separated by ‘&’.

Then, it is time to start with the example.

In this case, we have available some REST services implementing the CRUD operations for Books. The available verbs are:

  • GET: Recover all the items or a particular item.
  • POST: To create a new book.
  • PUT: To update the book information.
  • DELETE: To delete a concrete book.

The available URLs are:

  • /books (GET, POST)
  • /books/{id} (GET, PUT, DELETE)

The object book will be a very simple object with three properties:

  • id: It will be auto generated by the back-end.
  • author: It should be provided in creation time.
  • title: It should be provided in creation time.

Having this clear in our minds we can start.

Recover all the books (/books, GET) It is empty right now

curl -i -H "Accept: application/json" http://localhost:4567/books
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Server: Jetty(9.0.2.v20130417)

Create a new book (/books, POST)

curl -i -H "Accept: application/json" -X POST -d "author=john&title=unknown" http://localhost:4567/books
HTTP/1.1 201 Created
Content-Type: text/html; charset=UTF-8
Content-Length: 10
Server: Jetty(9.0.2.v20130417)

1354591741

Recover a concrete book (/books/{id}, GET)

curl -i -H "Accept: application/json" http://localhost:4567/books/1354591741
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 28
Server: Jetty(9.0.2.v20130417)

Title: unknown, Author: john

Update a book (/books, PUT)

curl -i -H "Accept: application/json " -X PUT -d "title=Sunshine" http://localhost:4567/books/1354591741
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 33
Server: Jetty(9.0.2.v20130417)

Book with id '1354591741' updated

Recover updated book (/books/{id}, GET)

curl -i -H "Accept: application/json" http://localhost:4567/books/1354591741
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 29
Server: Jetty(9.0.2.v20130417)

Title: Sunshine, Author: john

Delete a book (/books/{id}, DELETE)

curl -i -H "Accept: application/json" -X DELETE http://localhost:4567/books/1354591741
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 33
Server: Jetty(9.0.2.v20130417)

Book with id '1354591741' deleted

Recover deleted book (/books/{id}, GET)

curl -i -H "Accept: application/json " http://localhost:4567/books/1354591741
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Content-Length: 14
Server: Jetty(9.0.2.v20130417)

Book not found

With all the previous instructions we can test and check REST services implementing CRUD operations. It is a very easy and quick way, and if you use to use the console or terminal you will find it easier than use other tools.

Obviously, there are more ways to use it, for example, if your REST services expect a file, but the purpose of this post was only do a little introduction to the tool and to have a place to check the syntax quickly.

See you.

Testing REST with cURL