Skip to content

olle/tolerant-mapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status

Hi, have you heard about TolerantReader?

Yes, sure! Why?

Well, I'm in this project, we're building a solution based on services and messaging in order to enforce loose coupling.

Ok, sounds interesting.

Yeah, it is. It's just that... well we're trying to come up with a solution for shared data formats between the end-points.

I understand.

And the thing is, we're currently building a lot of libraries with data transfer object types that we share among all the teams and projects, that are using the services.

Hmm... ok, sounds like you are pretty much not loosely coupled at all.

...well, yeah.

Too bad.

...yes.

But you were asking if I knew about TolerantReader.

Oh, yes. Well I'm wondering if you could help me to find a solution more in that direction?

Of course. Have a look at this

public final class Person {

   @Path("id")
   private Long id;

   @Path("username")
   private String name;

   @Path("details.email")
   private String email;

   @Path("details.phone.work")
   private String phone;

   @Path("details.phone.mobile")
   private String mobile;
}

What do you see?

It's a POJO, with some annotated fields.

That's right. Now the Path annotation describes a mapping to another data structure. Does it look familiar?

Yeah it looks like some kind of object notation format... is it JSON?

It could be. Or just a plain map where each dot is a traversal into another map, like a tree structure.

Cool.

Now the neat thing is that if the external data format changes, we could simply update our mapping, like this:

public final class Person {

   @Path("id")
   private Long id;

   @Path("details.fullName")
   private String name;

   @Path("details.email.primary")
   private String email;

   @Path("details.phone.work")
   private String phone;

   @Path("details.phone.mobile")
   private String mobile;
}

It's of course important not to change the semantics of the internal representation, but as you see we're fully open to adapt to the external format change, without modifying our internal type.

Wow. Great!

It even works with optional data, like this:

public final class Person {

   @Path("id")
   private Long id;

   @Path("details.fullName")
   private String name;

   @Path("details.email.primary")
   private String email;

   @Path("details.phone.work")
   private String phone;

   @Path("details.phone.mobile")
   private String mobile;

   @Path("details.twitter")
   private Optional<String> twitter;
   @Path("details.web")
   private Optional<String> web;
}

Optional fields are perfect for this type of data, without the need to add silly null-checks all over your code.

Oh, and check this out - you can reference fields in arrays or collections, by index, so if you need to map just some properties of a list, it's easy.

public final class ContactInfo {

  @Path("user.vcard.phone(3)")
  private String mobile;

  @Path("user.vcard.phone(1)")
  private String work

  @Path("user.vcard.address.lines[0]")
  String street;
  @Path("user.vcard.address.lines[1]")
  String postalCode;
  @Path("user.vcard.address.lines[2]")
  String city;
  @Path("user.vcard.address.lines[3]")
  String country;
}

Perfect! This looks great, so how do I get started?

You can simply use tolerant-mapper as a library in your project. Just include it as a Maven dependency from the Jitpack repository. Then simply add the dependency:

<dependency>
    <!-- From Jitpack-repo -->
    <groupId>com.github.olle</groupId>
    <artifactId>tolerant-mapper</artifactId>
    <version>${SOME-TAG}</version>
</dependency>

Better check out the current releases for a suitable version though.

Wow, sounds great! I'm going to make sure to check out Jitpack, and read up on how to configure that repository.

But how do I actually use the tolerant-mapper library then?

For now, have a look inside the src/test/java/ directory, look at the MapperTest. It describes the general idea, until I get the chance to add some more documentation. Ok?

Thank you! Finally, decoupling and services without the problem of data transfer formats.

Glad I could help. And happy hacking!