Showing posts with label Spring-Data. Show all posts
Showing posts with label Spring-Data. Show all posts

Tuesday, July 30, 2013

Why REST is so important

This post is dedicated to REST, an architectural style of shaping webservices and one of the most misunderstood concept in the history of IT. This post is addressed to you who is designing webservice apis not being fully aware what REST actually means. I'm trying to give you the idea. This post is also addressed to you who think to know what REST means, when in reality you have no clue, just yet. Yes i have met such people in the past - plenty of them. It's not going into the details of the Richardson Maturity Model, and it's not gonna make you a REST expert. There are plenty of guides on the web for that: slides, youtube videos, blogposts, books and more. Rather than going into the details, i'm going to link some good resources at the end of this post.

So lets start with

The meaning of REST

Representational State Transfer. This sentence is not only what REST stands for, it is also the tiniest possible description of what REST actually means. Didn't get it? Read it again: Representational State Transfer. It is not a standard, rather a style describing the act of transfering a state of something by its representation.

Lets consider this:
Marcus is a farmer. He has a ranch with 4 pigs, 12 chickens and 3 cows. He is now simulating a REST api while i am the client. If i want to request the current state of his farm using REST i just ask him: "State?"
Marcus answers: "4 pigs, 12 chickens, 3 cows".
This is the most simple example of Representional State Transfer. Marcus transfered the state of his farm to me using a representation. The representation of the farm is the plain sentence: "4 pigs, 12 chickens, 3 cows".

So lets get to the next level. How would i tell Marcus to add 2 cows to his farm the REST way?
Maybe tell him: "Marcus, please add 2 cows to your farm".
Do you think this was REST? Are we transfering state by its representation here? NO! This was calling a remote procedure. The procedure of adding 2 cows to the farm.
Marcus sadly answers: "400, Bad Request. What do you mean?"
So lets try this again. How would we do this the REST way? What was the representation again? It was "4 pigs, 12 chickens, 3 cows". Ok. so lets try this again transfering the representation...
me: "Marcus, ... 4 pigs, 12 chickens, 5 cows ... please!".
Marcus: "Alright !".
me: "Marcus, ... what is your state now?".
Marcus: "4 pigs, 12 chickens, 5 cows".
me: "Ahh, great!"
See? It was really not that hard and it was REST.

Why RPC is a pain in the A**

So why would you favor REST over the remote procedure call (=RPC) from a logical perspective? Because it dramatically reduces the complexity of our communication by making the representation our only contract. We do not have to discuss what kinds of procedures we need (Add a cow?, Add an animal of a type? Double the chickens amount? Remove all pigs?). All we have to discuss is the representation, and use this representation to achieve anything we want. Easy, isn't it? The needless complexity of RPC is not helpful at all. It is rather increasing the risk of misunderstandings, which we don't want. We don't want our communication to fail because Marcus and I understood a procedure differently.
But this is just one of many problems RPC is creating. If you want to use RPC you need to design some kind of structure to embed your procedure into. This structure requires a place to store parameters, error codes, return values and so on. I have seen lots of developers and companies who really did this. They designed their own RPC-Structure arising huge problems in the implementation of clients and client-server interaction. Why would you do this? Why would you invent your own RPC-Structure? Do you think this is helpful? What if i wanted to make an application that uses many WebServices of multiple proprietary RPC-Formats? I would have to develop something like this:
image #1

Ugh...
If you really need RPC, at least choose a standard like SOAP. Don't make up your own stuff!

But SOAP is still bad

Still, even the standards of RPC are really painful. Well, i have to admit that with ACID Transactions, and a complete standardized Service Description Language, SOAP is not all that bad in some circumstances. Nevertheless, the overhead SOAP produces is massive and a huge performance killer. HTTP is a lightweight protocol. Its headers include anything you need. The only thing you want to put in the body is a representation - or not even that.

Sessions are Evil

Since i wrote solely about sessions and why they are bad in another post, i removed this paragraph. Please continue reading here: Sessions. A Pitfall

Dont reinvent Hypermedia

Since hypermedia is getting quite popular now, i beg you: Don't invent your own style.
We do already have plenty. There is
And we are slowly getting to the situation in image #1 again.

Further Resources

In this post, i have only scratched the surface of the advantages of REST.
Here are some good resources to get you a deeper understanding.

Wednesday, March 6, 2013

Avoid too many Parameters using the Builder Pattern

Today i want to show you another way to use the Builder Pattern. From what i've seen there are tons of examples of the Builder Pattern online. But they do all have one thing in common: They are used to create an Instance of an Object and "replace" its constructor. This way you can create a complex Object in a very clean and readable fashion using a Fluent Interface.

Other than that, there is also a slightly different way you can benefit of the Builder Pattern. Think of a Method with like 10 Parameters. Thats not quite nice, and should not ever happen. Robert C. Martin recommends a maximum amount of 3 Parameters in his book: Clean Code. You should rather use some kind of a Config Object holding those 10 parameters, to clean it up. But lets say, you have a BookService Class with a find(..) method, that allows to search by 10 different parameters, and every single one of them is optional. You could use the Builder Pattern with some kind of Query Object to solve the problem.

As we should always program against Interfaces to keep things modular, ill start with the Interface:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface BookService {

    public Book create(Book book);

    public void delete(String isbn);

    public Query query();

    public interface Query {

        public Query isName(String name);

        public Query hasAuthor(String author);

        public Query isCheaperThan(Float price);

        public Query isIsbn(String isbn);

        public Query hasMorePagesThan(Long pages);

        public Query isAvailable();

        public List<Book> find();

    }
}

So the Interface looks pretty neat. It allows you to write something like:

bookService.query().hasAuthor("Bob").isCheaperThan(20.9).isAvailable().find();

While the Query could be considered as an implementation of the Query Object pattern it is not tied to any Database related stuff, which is very important. You dont want to be tied to Criteria Queries or SQL in this Layer. It should be independent of any implementation (e.g. Database or Filesystem).

To clear things up, i want to show you an implementation example using Spring-Data. I am a big fan of Spring-Data, since it allows you to create full featured DAOs with little to no Programming effort for many different Persistence Providers. If you havent used it yet, you should definitely give it a try.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@Transactional
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    // ...

    @Override
    @Transactional(readOnly=true)
    public Query query() {
        return new QueryImpl(this.bookRepository);
    }

    public class QueryImpl implements Query{

        private BookRepository bookRepository;
        private Specifications<Book> filters = null;

        public QueryImpl(BookRepository bookRepository) {
            this.bookRepository = bookRepository;
        }

        private void addFilter(Specification<FlowMessage> filter) {
            filters = (filters == null) ? where(filter) : filters.and(filter);
        }

        public Query isName(String name) {
            if (name == null) return this;
            addFilter(BookSpecifications.isName(name));
            return this;
        }

        public Query hasAuthor(String author) {
            if (author == null) return this;
            addFilter(BookSpecifications.hasAuthor(author));
            return this;
        }

        // other criterias ...

        public List<Book> find() {
            return this.bookRepository.findAll(filters);
        }
    }
}

As you can see i am just joining filter Criterias together, and thats it. The implementation is really simple but also expandable. These filter Criterias are supported by my BookRepository (=DAO). I just have to define them in a helper class first. Check out this and that for a deeper understanding how to combine spring-data with criteria queries.