Serializing Java objects for REST API Requests in Open Event Organizer App

Open Event Organizer App is a client side application which uses REST API for network requests. The server supports sending and receiving of data only in JSONAPI spec, so, we needed to serialize java models into JSON objects and deserialize JSON data into java models following JSONAPI spec. To achieve this we followed the following steps. Specifications We will be using jasminb/jsonapi-converter which handles request/response parsing of models following JSONAPI Spec and Retrofit plugin of jackson converter to serializing JSON to Java Models and vice versa. Let’s create a java model. We are using some annotations provided by Lombok library to avoid writing boilerplate code. @JsonNaming annotation is used to apply KebabCaseStrategy while serializing fields @Data @Type("order") @AllArgsConstructor @JsonNaming(PropertyNamingStrategy.KebabCaseStrategy.class) @Table(database = OrgaDatabase.class, allFields = true) public class Order { @PrimaryKey @Id(LongIdHandler.class) public Long id; public float amount; public String completedAt; public String identifier; public String paidVia; public String paymentMode; public String status; @Relationship("event") @ForeignKey(stubbedRelationship = true, onDelete = ForeignKeyAction.CASCADE) public Event event; public Order() { } } In the NetworkModule class, there is a method providesMappedClasses() containing a list of classes that needs to be serialized/deserialized. We need to add the above model in the list. Then, this list is provided to Singleton instance of JSONAPIConvertorFactory through Dagger. JSONAPIConvertorFactory uses the Retrofit ObjectMapper and maps the classes that are handled by this instance. @Provides Class[] providesMappedClasses() { return new Class[]{Event.class, Attendee.class, Ticket.class, Order.class}; } Further, various serialization properties can be used while building Singleton ObjectMapper instance. Adding any properties here ensures that these are applied to all the mapped classes by JSONAPIConvertorFactory. For eg, we are using the serialization property to throw an exception and fail whenever empty beans are encountered. @Provides @Singleton ObjectMapper providesObjectMapper() { return new ObjectMapper() .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) // Handle constant breaking changes in API by not including null fields // TODO: Remove when API stabilizes and/or need to include null values is there .setSerializationInclusion(JsonInclude.Include.NON_ABSENT); } Resources Github Repository for jsonapi-converter https://github.com/jasminb/jsonapi-converter Github repository for Jackson Retrofit Plugin https://github.com/square/retrofit/tree/master/retrofit-converters/jackson Official Website for Project Lombok https://projectlombok.org/ Github Repository for Open-Event-Orga-App https://github.com/fossasia/open-event-orga-app

Continue ReadingSerializing Java objects for REST API Requests in Open Event Organizer App

Using Lombok to Reduce Boilerplate Code in Open Event Android App

The Open Even App Android project contains data/model classes like Event, Track, Session, Speaker etc which are used to fetch data from the server and store data in the database. Each model contains private fields, getters, setters and toString() method which are used to change data of the object, access data of the object, logging and debugging. Adding all these methods manually makes the code boilerplate. In this blog post I explain how to use Lombok to reduce boilerplate code in the model class. Add dependency To set up Lombok for your application you have to add the dependency in your app module’s build.gradle file. dependencies { provided "org.projectlombok:lombok:1.16.18" } Install Lombok plugin In addition to setting up your gradle project correctly, you need to add the Lombok IntelliJ plugin to add Lombok support to Android Studio Go to File > Settings > Plugins Click on Browse repositories Search for Lombok Plugin Click on Install plugin Restart Android Studio Write model class Lombok has annotations to generate Getters, Setters, Constructors, toString(), Equal() and hashCode() methods. @Getter,  @Setter, @ToString, @EqualsAndHashCode @Data is a shortcut annotation that bundles the features of @Getter, @Setter, @ToString and @EqualsAndHashCode Here I am only defining track model because of its simplicity and less complexity. @Data public class Track { private int id; private String name; private String description; private String color; private String fontColor; private RealmList<Session> sessions; } Create and use object After defining models you can create an instance of the object and you will notice that you can access all the getters and setters. Track track = new Track(); track.setName("Android"); String name = track.getName(); // here value of name will be "Android" You can also specify which fields to include and exclude in the toString(), equals() and hashCode() methods using @ToString, @EqualsAndHashCode annotation. @ToString(of={"id", "name"}) @ToString(exclude="color") @EqualsAndHashCode(of={"id", "name"}) @EqualsAndHashCode(exclude={"color", "fontColor"}) Constructors Lombok has three methods to generator constructors @NoArgsConstructor: It generates constructor with no parameters @RequiredArgsConstructor: It generates a constructor with 1 parameter for each field that requires special handling. @AllArgsConstructor: It generates a constructor with 1 parameter for each field in your class. Conclusion As you can see, Lombok uses succinct annotations to generate methods such as getters, setters, and constructors. It can easily help you get rid of hundreds of lines of boilerplate code. Lombok also allows you to make your code more expressive, concise and can help you avoid some bugs. To learn more about Lombok project follow the links given below. Lombok: https://projectlombok.org/features/all Tutorial: http://www.baeldung.com/intro-to-project-lombok

Continue ReadingUsing Lombok to Reduce Boilerplate Code in Open Event Android App

Shrinking Model Classes Boilerplate in Open Event Android Projects Using Jackson and Lombok

JSON is the de facto standard format used for REST API communication, and for consuming any of such API on Android apps like Open Event Android Client and Organiser App, we need Plain Old Java Objects, or POJOs to map the JSON attributes to class properties. These are called models, for they model the API response or request. Basic structure of these models contain Private properties representing JSON attributes Getters and Setters for these properties used to change the object or access its data A toString() method which converts object state to a string, useful for logging and debugging purposes An equals and hashcode method if we want to compare two objects These can be easily and automatically be generated by any modern IDE, but add unnecessarily to the code base for a relatively simple model class, and are also difficult to maintain. If you add, remove, or rename a method, you have to change its getters/setters, toString and other standard data class methods. There are a couple of ways to handle it: Google’s Auto Value: Creates Immutable class builders and creators, with all standard methods. But, as it generates a new class for the model, you need to add a library to make it work with JSON parsers and Retrofit. Secondly, there is no way to change the object attributes as they are immutable. It is generally a good practice to make your models immutable, but if you are manipulating their data in your application and saving it in your database, it won’t be possible except than to create a copy of that object. Secondly, not all database storage libraries support it Kotlin’s Data Classes: Kotlin has a nice way to made models using data classes, but it has certain limitations too. Only parameters in primary constructor will be included in the data methods generated, and for creating a no argument constructor (required for certain database libraries and annotation processors), you either need to assign default value to each property or call the primary constructor filling in all the default values, which is a boilerplate of its own. Secondly, sometimes 3rd party libraries are needed to work correctly with data classes on some JSON parsing frameworks, and you probably don’t want to just include Kotlin in your project just for data classes Lombok: We’ll be talking about it later in this blog Immutables, Xtend Lang, etc This is one kind of boilerplate, and other kind is JSON property names. As we know Java uses camelcase notation for properties, and JSON attributes are mostly: Snake Cased: property_name Kebab Cased: property-name Whether you are using GSON, Jackson or any other JSON parsing framework, it works great for non ambiguous property names which match as same in both JSON and Java, but requires special naming attributes for translating JSON attributes to camelcase and vice versa. Won’t you want your parser to intelligently convert property_name to propertyName without having you write the tedious mapping which is not only a boilerplate, but also error…

Continue ReadingShrinking Model Classes Boilerplate in Open Event Android Projects Using Jackson and Lombok