Changes in Jongo 0.2

Lots of changes are being introduced in Jongo 0.2 which I believe are better suited for the scope of the project.


First and most important, I decided to remove the administration console which was to be used as a way for an administrator to customize access to resources, set ID columns and add complex queries. The problem with this approach is that I don't want Jongo to be another tool you have to worry about to keep it running, and most of this things are already on your RDBMS! The basic idea of Jongo: embrace the use of any SQL server.






So, the problems the administration console tried to fix should be fixed on the database:


Resources permissions. Use an specific user for Jongo, and customize access for this user.


Complex Queries. The idea was to allow a GET request to execute a predefined query which was created in Jongo. But why do this when you have triggers, stored procedures, views, etc? So this had to go. Also, stored procedures run faster than running the same query over and over again.


http//.../Jongo/db/sp/myStoredProcedure


[Note: stored procedures are still not supported, but should be in the future]


Custom ID column. If your resource is not using an ID column, this is now supposed to be sent on the requests path:


http//.../Jongo/db/resource/1?customId=rid


Since the administration console is gone, there's no need for Jongo to keep a database to hold its data, so this and the hsqldb.jar were removed too.


Another big change being introduced is the correct use of headers in the request and in the response. In 0.1 the "Accept" header wasn't used at all, and this is not acceptable in REST. So now, instead of changing the format as a path parameter, Jongo handles the appropriate headers. 


$curl -H "Accept: application/xml" "http://.../jongo/db/user/1"


On the other hand, response headers include a lot of information about the data being returned: Content-Length, Content-MD5, Content-Count, Date and more depending on the response (error, success, head, stats).

HTTP/1.1 200 OK
Content-Type: application/xml
Content-Count: 1
Content-Location: user
Content-Length: 249
Date: 2012-03-30T12:38:11.581+02:00
Content-MD5: ulYx9Vsbymcq7ExWzdWlFw==
Server: Jetty(8.1.2.v20120308)


During the day I've been working extensively with JAX-RS at work with a project which is very similar to Jongo in how both work, so both of the projects share ideas, and being able to customize the response's JSON and XML is very important. Because of this Jongo will include some filters which will try to ease the unmarshalling in, for example, JAX applications, ExtJS and more.



<response>
  <success>OK</success>
  <resource>user</resource>
  <rows>
    <row>
      <cell>
        <birthday>1992-01-15</birthday>
        <credit>0.00</credit>
        <lastupdate>2012-03-30T12:38:11.576+02:00</lastupdate>
        <name>bar</name>
        <age>33</age>
        <id>1</id>
      </cell>
    </row>
  </rows>
</response>



By default the XML and JSON returned by Jongo is the same as in version 0.1 but if you configure Jongo's web.xml file to use no filter, then JAX is used to do the marshaling.



<response>

  <status>OK</status>
  <success>true</success>

  <resource>user</resource>
  <rows>
    <roi>0</roi>
    <cells>
      <entry>
        <key>BIRTHDAY</key>
        <value>1992-01-15</value>
      </entry>
      <entry>
        <key>CREDIT</key>
        <value>0.00</value>
      </entry>
      <entry>
        <key>LASTUPDATE</key>
        <value>2012-03-30T12:30:27.768+02:00</value>
      </entry>
      <entry>
        <key>NAME</key>
        <value>bar</value>
      </entry>
      <entry>
        <key>AGE</key>
        <value>33</value>
      </entry>
      <entry>
        <key>ID</key>
        <value>1</value>
      </entry>
    </cells>
  </rows>
</response>



The objective is to allow to develop different formats which can be read without much development on the consumers.


I'm also working on tests and trying to achieve a 90% coverage. Doing this is a great exercise on fixing code structure and abstraction. Being able to setup an in-memory database with HSQLDB also helps a lot.


Gone is all the code to handle the different database error codes returned by the JDBC drivers. I had the hope (silly me) that the different RDBMSs would follow some sort of standard at least on this, but no, each one of them returns a different SQLStatus & SQLCode for the same error, so it was very frustrating and I didn't want to waste my time researching for the correct codes and their meaning for every different system. The solution? 



<response>
  <success>false</success>
  <message>data exception: invalid character value for cast Query: SELECT * FROM user WHERE id = ? ORDER BY id ASC LIMIT 25 OFFSET 0 Parameters: [1*]</message>
  <sqlState>22018</sqlState>
  <sqlCode>-3438</sqlCode>
</response>



More than a solution, it's a workaround: return the error message and codes to the client and let it handle it as it sees fit. Remember, embrace your database!


Another feature gone is the "apps" folder, so by default, you won't be able to use Jongo as a JavaScript application server, although, there's a way to serve static content which I'll explain in the future.


Finally, I separated the project in three repositories:

  • jongo (common files)
  • jongo-jetty (standalone)
  • jongo-as (war)

I tried to get a version of this WAR working with Google's GAE but it was very frustrating as a PaaS. What I believe is a better service is the one provided by Jelastic and I'll document a guide on how to prepare Jongo's WAR to work with it.


That's it for now, I hope the few users of Jongo don't get pissed because of this changes.