Open Event Server – Pages API

This article illustrates how the Pages API has been designed and implemented on the server side, i.e., FOSSASIA‘s Open Event Server. Pages endpoint is used to create static pages such as “About Page” or any other page that doesn’t need to be updated frequently and only a specific content is to be shown. Parameters name - This stores the name of the page. Type - String Required - Yes title - This stores the title of the page. Type - String Required - No url - This stores the url of the page. Type - String Required - Yes description - This stores the description of the page. Type - String Required - Yes language - This stores the language of the page. Type - String Required - No index - This stores the position of the page. Type - Integer Required - No Default - 0 place - Location where the page will be placed. Type - String Required - No Accepted Values - ‘footer’ and ‘event’ These are the allowed parameters for the endpoint. Model Lets see how we model this API. The ORM looks like this : __tablename__ = 'pages' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String, nullable=False) title = db.Column(db.String) url = db.Column(db.String, nullable=False) description = db.Column(db.String) place = db.Column(db.String) language = db.Column(db.String) index = db.Column(db.Integer, default=0) As you can see, we created a table called “pages”. This table has 8 columns, 7 of which are the parameters that I have mentioned above. The column “id” is an Integer column and is the primary key column. This will help to differentiate between the various entries in the table. The visualisation for this table looks as follows : API We support the following operations: GET all the pages in the database POST create a new page GET details of a single page as per id PATCH a single page by id DELETE a single page by id To implement this we first add the routes in our python file as follows : api.route(PageList, 'page_list', '/pages') api.route(PageDetail, 'page_detail', '/pages/<int:id>') Then we define these classes to handle the requests. The first route looks as follows: class PageList(ResourceList):   """   List and create page   """   decorators = (api.has_permission('is_admin', methods="POST"),)   schema = PageSchema   data_layer = {'session': db.session,                 'model': Page} As can be seen above, this request requires the user to be an admin. It uses the Page model described above and handles a POST request. The second route is: class PageDetail(ResourceDetail):   """   Page detail by id   """   schema = PageSchema   decorators = (api.has_permission('is_admin', methods="PATCH,DELETE"),)   data_layer = {'session': db.session,                 'model': Page} This route also requires the user to be an admin. It uses the Page model and handles PATCH, DELETE requests. To summarise our APIs are: GET /v1/pages{?sort,filter} POST /v1/pages{?sort,filter} GET /v1/pages/{page_id} PATCH /v1/pages/{page_id} DELETE /v1/pages/{page_id} References Flask-Marshmallow SQLAlchemy Open Event Server Flask

Continue ReadingOpen Event Server – Pages API

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

Query Model Structure of Loklak Search

Need to restructure The earlier versions of loklak search applications had the issues of breaking changes whenever any new feature was added in the application. The main reason for these unintended bugs was identified to be the existing query structure. The query structure which was used in the earlier versions of the application only comprised of the single entity a string named as queryString. export interface Query { queryString: string; } This simple query string property was good enough for simple string based searches which were the goals of the application in the initial phases, but as the application progressed we realized this simple string based implementation is not going to be feasible for the long term. As there are only a limited things we can do with strings. It becomes extremely difficult to set and reset the portions of the string according to the requirements. This was the main vision for the alternate architecture design scheme was to the ease of enabling and disabling the features on the fly. Application Structure Therefore, to overcome the difficulties faced with the simple string based structure we introduced the concept of an attribute based structure for queries. The attribute based structure is simpler to understand and thus easier to maintain the state of the query in the application. export interface Query { displayString: string; queryString: string; routerString: string; filter: FilterList; location: string; timeBound: TimeBound; from: boolean; } The reason this is called an attribute based structure is that here each property of an interface is independent of one another. Thus each one can be thought of as a separate little key placed on the query, but each of these keys are different and are mutually exclusive. What this means is, if I want to write an attribute query, then it does not matter to me which other attributes are already present on the query. The query will eventually be processed and sent to the server and the corresponding valid results if exists will be shown to the user. Now the question arises how do we modify the values of these attributes? Now before answering this I would like to mention that this interface is actually instantiated in the the Redux state, so now our question automatically gets answered, the modification to redux state corresponding to the query structure will be done by specific reducers meant for modification of each attribute. These reducers are again triggered by corresponding actions. export const ActionTypes = { VALUE_CHANGE: '[Query] Value Change', FILTER_CHANGE: '[Query] Filter Change', LOCATION_CHANGE: '[Query] Location Change', TIME_BOUND_CHANGE: '[Query] Time Bound Change', }; This ActionTypes object contains the the corresponding actions which are used to trigger the reducers. These actions can be dispatched in response to any user interaction by any of the components, thus modifying a particular state attribute via the reducer. Converting from object to string Now for our API endpoint to understand our query we need to send the proper string in API accepted format. For this there is need to…

Continue ReadingQuery Model Structure of Loklak Search

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