I remember these days when building something similar in Java required much more body movements, and maybe this was the reason to why some start-ups have chosen other weak typing languages with all their fancy Web frameworks for rapid bootstrapping. This isn't the case anymore, see how easy is creating a REST service that supports all CRUD operations in Java:
1. Define your task model:
/**
* Task model
*/
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String text;
private Date created = new Date();
private Date completed;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getCompleted() {
return completed;
}
public void setCompleted(Date completed) {
this.completed = completed;
}
}
2. Tell what operations on tasks you're going to support:
/**
* This class defines DB operations on Task entity
*/
public interface TaskRepository extends PagingAndSortingRepository<Task> {
// Magic method name automatically generates needed query
public List<Task> findByCompletedIsNull();
}
3. Configure your application:
/**
* This class is responsible for:
* - Setting up DB connection and ORM
* - Initializing REST service for all found entities
* - Starting Spring application (main entry point)
*/
@ComponentScan
@Configuration
@EnableAutoConfiguration
@EnableJpaRepositories
@EnableTransactionManagement
public class Application extends RepositoryRestMvcConfiguration {
@Bean
public DataSource dataSource() throws PropertyVetoException {
MySQLDataSource dataSource = new MySQLDataSource();
dataSource.setDatabaseName("taskdb");
dataSource.setUserName("user");
dataSource.setPassword("pass");
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
// Database tables will be created/updated automatically due to this:
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setDatabase(Database.MYSQL);
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
entityManagerFactoryBean.setPackagesToScan(getClass().getPackage().getName());
return entityManagerFactoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
That's all! After invoking this application, you'll get a task complete REST service for free. Let's test it:
Create a new task:
~$ curl -X POST -H "Content-Type: application/json" -d '{"text":"Implement simplest REST Java application"}' http://localhost:8080/tasks
See the task contents:
~$ curl http://localhost:8080/tasks/1
{
"text" : "Implement simplest REST Java application",
"created" : 1395665199000,
"completed" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/tasks/1"
}
}
}
Create another task:
~$ curl -X POST -H "Content-Type: application/json" -d '{"text":"Go home"}' http://localhost:8080/tasks
Find all tasks:
~$ curl http://localhost:8080/tasks
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/tasks{?page,size,sort}",
"templated" : true
},
"search" : {
"href" : "http://localhost:8080/tasks/search"
}
},
"_embedded" : {
"tasks" : [ {
"text" : "Implement simplest REST Java application",
"created" : 1395665199000,
"completed" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/tasks/1"
}
}
}, {
"text" : "Go home",
"created" : 1395665359000,
"completed" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/tasks/2"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 2,
"totalPages" : 1,
"number" : 0
}
}
(pay an attention to how easy is it implementing pagination using this REST service!)
Mark the first task as complete:
~$ curl -X PATCH -H "Content-Type: application/json" -d "{\"completed\":$(($(date +%s)*1000))}" http://localhost:8080/tasks/1
Find incomplete tasks:
~$ curl http://localhost:8080/tasks/search/findByCompletedIsNull
{
"_embedded" : {
"tasks" : [ {
"text" : "Go home",
"created" : 1395665359000,
"completed" : null,
"_links" : {
"self" : {
"href" : "http://localhost:8080/tasks/2"
}
}
} ]
}
}
Pretty easy and yet powerful, huh?
For more information and instructions for how to compile and run this application, see source code on GitHub.


.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
.jpg)
