Tuesday, January 19, 2016

How to create REST web services in pure java as easy as with node.js - This is so beautiful!!!

Hi there!

Today i'm gonna show you how to create REST web services as fast and as simple as with node.js, but with PURE java!!! Yes!!!! it is possible and so beautiful and clean :) I love it and i am sure you'll love it too, if you love java like i do. ;)

Now a days everybody is using and speaking from node.js, javascript, angular, ruby, etc. There are so many "frameworks" to do "more or less" the same thing, that i was wondering me, if there was nothing to help the java-community with. And yessssss...... there is! :)

Putting things together and inspired by the post of "creating REST api quickly using java" i decided to give them a try and create a more detailed post of it. It works so fine and nice that i must share it with you!

Technologies involved


  • We will be using SparkJava which is a tiny, compact framework, designed to develop web applications with minimal effort.
  • To create DAO's out of the box and manipulate database as easy as like stealing candy from a babies... :) we will use ormlite jdbc for java. Another great tool i love.
  • As a database we will use MySQL. 


Don't worry, we will see how to add those tools to your project in a few minutes step by step. There is no mystery using it.

Creating a maven project

With your IDE, i use eclipse Enide 2015, Version: Mars Release (4.5.0), Build id: Nodeclipse-20150706-0921 in this example, create a simple maven project like that:





Open the pom.xml and insert the following code to get the jars from spark, ormlite and mysql-connector:

<!-- library dependencies -->
<dependencies>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-jdbc</artifactId>
<version>4.48</version>
</dependency>


<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>

Defining an Entity User

Well, now we are fine to start with our service. Let's define first an user class. Use the code snippet bellow:

package com.companyname.modulename.server.model;

import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
 
@DatabaseTable(tableName = "users")
public class User {
    
    @DatabaseField(generatedId = true)
    private int id;
    
    @DatabaseField
    private String username;
    
    @DatabaseField
    private String email;
    
    public User() {
        // ORMLite needs a no-arg constructor 
    }
    
    public int getId() {
        return this.id;
    }
    
    public String getUsername() {    
        return this.username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
}

Defining the Server with the services inside

Now to the cool things. :) Let's define a GET and POST method to insert and retrieve data from the database.

package com.companyname.modulename.server;

import static spark.Spark.get;
import static spark.Spark.post;

import java.sql.SQLException;

import com.companyname.modulename.server.model.User;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils;

import spark.Request;
import spark.Response;
import spark.Route;

public class Server {

 private static Dao userDao;
 // other DAO's my be defined here...

 // TUTORIAL EXECUTION DATE: 18/01/2016
 // IMPORTANT: Before runnning this class: make sure your mysql server is running
 //
 // Run as > Java Application... Than you should see a message similar to
 // that bellow:
 //
 // [Thread-0] INFO spark.webserver.SparkServer - == Spark has ignited ...
 // [Thread-0] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:4567
 // [Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.0.2.v20130417
 // [Thread-0] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@6255aad1{HTTP/1.1}{0.0.0.0:4567}
 // [qtp1296900317-19] INFO spark.webserver.MatcherFilter - The requested route [/favicon.ico] has not been mapped in Spark
 
 
 // In your Browser type in: http://localhost:4567/users/1
 // than you should see: User: username=test, email=test@test.net
 public static void main(String[] args) throws SQLException {
  initMySQL();

  // define the http action methods here...
  // get sample: http://localhost:4567/users/1
  get("/users/:id", new Route() {
   public Object handle(Request req, Response res) throws Exception {
    final User user = userDao.queryForId(req.params(":id"));
    if (user != null) {
     return "Username: " + user.getUsername(); // or JSON? :-)
    } else {
     final int httpNotFound = 404;
     final String msg = "User not found";
     res.status(httpNotFound); 
     return msg;
    }
   }
  });

  // post sample: (using postman)
  // http://localhost:4567/users?username=ricardo&email=ricardo@test.com
  post("/users", new Route() {
   public Object handle(Request request, Response response) throws SQLException {
    final String username = request.queryParams("username");
    final String email = request.queryParams("email");

    final User user = new User();
    user.setUsername(username);
    user.setEmail(email);

    final int createdUserId = userDao.create(user);
    final int httpCreated = 201;
    response.status(httpCreated);
    return createdUserId;
   }
  });
 }

 // make sure your mysql server is running, than:
 // connect and start to previously created MySQL database called spark
 // with username: root and password: 123456
 private static void initMySQL() throws SQLException {
  final String databaseUrl = "jdbc:mysql://localhost/spark";
  final ConnectionSource connectionSource = new JdbcConnectionSource(databaseUrl);
  ((JdbcConnectionSource) connectionSource).setUsername("root");
  ((JdbcConnectionSource) connectionSource).setPassword("123456");
  // creates tables and DAO's to be used in GET/POST or whatever 
  // you may define in main method
  createTablesIfNotExitsAlready(connectionSource);
  initDAOs(connectionSource);
 }

 private static void createTablesIfNotExitsAlready(final ConnectionSource connectionSource) throws SQLException {
  TableUtils.createTableIfNotExists(connectionSource, User.class);
  // other tables may be defined here...
 }

 private static void initDAOs(final ConnectionSource connectionSource) throws SQLException {
  userDao = DaoManager.createDao(connectionSource, User.class);
  // other DAO's may be defined here...
 }

}


Creating the database

Just one more thing! :) Before you can run this, make sure you have created the database called spark with user root and password 123456. To do so, under linux, first install the mysql server by typing this line in your terminal: (to open a terminal press Ctrl+Alt+T)

  • sudo apt-get install mysql-server


When the installer prompts the window to define the password for the root user, type 123456 and complete the installation.

Creating the Table User with MySQL Workbench

That is a nice exercise. I was not used to it, and that's way i'm showing it here also. Download it and double click it to install from here https://dev.mysql.com/downloads/workbench/ Once you are done with, start it and create a new db called spark like that:

Once you've opened it, there should be a connection available. This is the connection you've previously installed. Double click it and connect with your credentials. root and 123456


Than this window will open. Here create a new schema called spark and inside of it, create a table called User with id, username and email like shown bellow(the record there will not appear yet, be patient :)


Lets play with now!

Ok, now we are fine. Note that we have not written much code. Most of the work was infrastructure. Real code there is almost nothing. Ormlite abstracts table creation, manipulation and so on. Spark defines urls and http actions. Ok, if everything went well, you should be able to run the Server.class as Java Application. You should see the following statement in the console(which means your server is running well and the service is listening to it on port 4567):

[main] INFO com.j256.ormlite.table.TableUtils - creating table 'users'
[main] INFO com.j256.ormlite.table.TableUtils - executed create table statement changed 0 rows: CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER AUTO_INCREMENT , `username` VARCHAR(255) , `email` VARCHAR(255) , PRIMARY KEY (`id`) ) ENGINE=InnoDB 
[Thread-0] INFO spark.webserver.SparkServer - == Spark has ignited ...
[Thread-0] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:4567
[Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.0.2.v20130417
[Thread-0] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@2695c365{HTTP/1.1}{0.0.0.0:4567}

Testing the service

Well, now we should be able to test our services. Lets POST something using postman.



After that, try to execute a GET to retrieve the previous inserted data.


You could also check the data in the database by running this command line:
SELECT * FROM spark.users; You should see the record now:


That's all! hope you like it! :)


😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘‡

Be sure to read, it will change your life!
Show your work by Austin Kleonhttps://amzn.to/34NVmwx

This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practiceshttps://amzn.to/30WQSm2

Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv

This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp

Needless to say, these are top right?
Apple AirPods Pro: https://amzn.to/2GOICxy

😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO ðŸ˜±ðŸ‘†