Net-A-Sparkle

At NAP, our code bases have organically grown as we’ve added more capabilities in order to support the rapid growth of our business.

From Monolithic to Microservices

The microservices architecture is an alternative pattern that addresses the limitations of the monolithic architecture. With Microservices the ambition is to be small. The flexibility that comes from Microservices is driven largely because of their size, so to keep these benefits we need to fight against the urge to add more and more lines of code.

Some core principles of a Microservice:

  • small, and focused on doing one thing well
  • a separate, independent process
  • communicates via language agnostic APIs
  • highly decoupled

A move to a Microservice Architecture aids in adopting new technology more quickly, and understanding how new advancements may help us. One of the biggest barriers to trying out and adopting new technology is the risk associated with it.

With our monolithic applications, if teams want to try a new programming language, database or framework, any change will impact a large amount of our systems, which is high risk. With an Architecture consisting of multiple services, teams have multiple new places in which to try out a new piece of technology. They can pick a service which is perhaps low risk and use the technology there, knowing that they can limit any potential negative impact.

Many organisations find that having this ability to more quickly absorb new technologies becomes a real advantage for them.

From Microservices to Microframeworks

There are many Java microframeworks out there, such as Dropwizard & Spring Boot, in this article we will be looking at sparkjava.

What is Spark?

Spark is a Java-based microframework for building web applications quickly. It is inspired by a framework written in Ruby called Sinatra.

Spark aims for simplicity and provides only a minimal set of features. However, it provides everything needed to build a web application in a few lines of Java code.

Show me some code

Let’s start with a simple Domain Class Customer.


public class Customer {

private String id;

@NotBlank
private String name;

@NotBlank
@Email
private String email;

public Customer(@NotBlank String name, @NotBlank String email) {
this.id = UUID.randomUUID().toString();
this.name = name;
this.email = email;
}
...

And some CRUD Operations


public class CustomerService {

private Map customers = new ConcurrentHashMap();

public List getCustomers() {
return customers.values().stream().collect(toList());
}

public Customer getCustomer(String id) {
return Optional.ofNullable(customers.get(id)).orElseThrow(() -> new NoSuchElementException("Customer could not be found for id: " + id));
}

public Customer createCustomer(String name,String email) {
Customer customer = new Customer(name, email);
customers.put(customer.getId(), customer);
return customer;
}

public Customer updateCustomer(String id, String name, String email) {
Optional customer = Optional.ofNullable(customers.get(id));
customer.ifPresent(c -> c.setName(name));
customer.ifPresent(c -> c.setEmail(email));
return customer.orElseThrow(() -> new NoSuchElementException("Customer could not be updated for id: " + id));
}

}

Now the REST bit…


public class CustomerController {

public CustomerController(final CustomerService customerService, final JsonTransformer jsonTransformer) {

get("/customer/:id", (req, res) -> {
String id = req.params(":id");
return customerService.getCustomer(id);
}, jsonTransformer);

get("/customers/", (req, res) -> {
return customerService.getCustomers();
}, jsonTransformer);

/**
* e.g curl -XPOST http://localhost:4567/customer?name=James&email=james.hoare@email.com
*/
post("/customer", (req, res) -> {
res.status(201);
return customerService.createCustomer(req.queryParams("name"), req.queryParams("email"));
}, jsonTransformer);

put("/customer/:id", (req, res) -> customerService.updateCustomer(
req.params(":id"),
req.queryParams("name"),
req.queryParams("email")
), jsonTransformer);

}

Now we just need to wire the application


public class Main {

/**
* Wire the Application
*
* @param args
*/
public static void main(String[] args) {

new CustomerController(new CustomerService(), new JsonTransformer());

}
}

Summary

Compared to Dropwizard and Spring Boot, Spark just provides the basics. However, it is so simple you can build small web applications extremely quickly — even better with Java 8!

The code for the demo application is available on github

Print Friendly
This entry was posted in Architecture, Java, Open Source, Software Engineering by Ho-r-ay. Bookmark the permalink.

About Ho-r-ay

James is NET-A-PORTER's Chief Technical Architect. He is responsible for NET-A-PORTER's Technical Direction and Leads a small team of highly-skilled Architects who carry out a wide range of activities, from actively writing code as a member of delivery teams and breaking down complex problems and identifying steps towards solutions.

Leave a Reply