Tuesday, April 21, 2020

Developing for Android

I'm frankly surprised that it's taken me so long to get around to making a post of this flavor, but here we are.  Unless you've been living under a rock for the last 10 or so years, you know that Android is the dominant player in the mobile operating system landscape.  Because Android is "open" (sometimes to its own detriment) and capable of running on so many different types of devices, its usage numbers tower over those of iOS.

So what of the prospects of easy, enjoyable development?  I took a brief look at iOS a few years back, and unless things have changed dramatically over the last few years, it's bleak.  It's a very opinionated ecosystem.  I was thrilled at the prospect of Swift when it was announced.  It was initially a very lightweight, terse and flexible language.  I read the entire spec over the course of a few days and couldn't wait to tear into a slew of side projects.  But it became clear to me over the course of a few short weeks that Apple's initial vision wouldn't stick.  The average iOS developer was more than comfortable with the quirks of Objective-C and the ingrained history of Xcode.  Today, Swift looks like a chimera of the original vision and the angular oddity of Objective-C, and Xcode is as opaque and user-unfriendly as ever.  As I mentioned in my earlier entry, JetBrains offered AppCode, which was much more comfortable for me initially, but was clearly losing to Xcode in the game of catch-up.

Now, as for Android, its development prospects seemed to have one major advantage out of the gates.  The default development tool is Android Studio, an IDE created by none other than JetBrains and based on the much-loved IntelliJ environment.  You can also simply use IntelliJ, as it includes all of the Android plugins.  

Android Studio/IntelliJ's simulator
In typical JetBrains fashion, the boilerplate work of laying down the foundation for your app is handled by the IDE.  You can pick from a number of templates to bootstrap the project, and it takes care of generating not only the dependency management (via Gradle), but also setting up the basic stubs, allowing you to immediately run your app via the emulator.  You can also easily download whichever flavor of Android you need.  Bear in mind that these are rather large, and downloading all of the revisions would fill up even the largest hard drive in no time.  

On the surface, developing for Android is a snap.  Once Gradle has pulled down all of your dependencies, you can start the emulator of your choice and boot up/restart your app in seconds.  When it gets down to the nuts and bolts of the actual development, however, I find myself to be a little less impressed.  I've shared my foray into Android land on my GitHub.  It's a pretty vanilla application, using some of the basic components to build a basic experience.

I've mentioned on a few previous occasions that Android has adopted Kotlin as a "native" language, and indeed as its language of the future.  It's probably a wise move given that Oracle and Alphabet/Google are competitors in many ways.  As I've delved deeper into it, I'd say I'm conflicted about Kotlin.  It seems like it's often different for the sake of being different, and it doesn't lend itself to easy adoption coming from a Java background.  I do appreciate its built-in nod to mutability/immutability, and it lifted its closure/lambda syntax directly from Groovy (which is always a plus for me).  But the language can seem unwieldy at times.  For better or worse, it is always going to result in less code than its Java equivalent, but it can be at the expense of clearly capturing the developer's intentions.  Fortunately, this isn't a huge issue with the app that I developed.  The logic is simple, and the flow of things should be pretty clear.

I'd say my main gripe with my development exercise is the default dependence upon XML.  For those of us that have been in the game for a minute, it's easy to recall when XML was the only game in town.  At the time, it was a revelation: it allowed a plain-text representation of any data structure you could think of.  Then JSON came along and ushered in a new era.  The fact that XML is so pervasive in Android development speaks to how long the platform has been around.  Mind you, it's clear to me that Android is undergoing a rapid evolution even as I type this: I don't think that XML will be the way of the future.  But the reality is that it's still the path of least resistance, and in my readings, it's still the most popular way of designing layouts.
A simple XML layout
IntelliJ's visual layout/widget editor
Fortunately, as you can see above, IntelliJ takes some of the guesswork out of how your components/layouts will look.  I still found myself daunted by the tedium of tweaking the XML, setting up the right namespaces and staying ahead of the ruddy trail of deprecations (there are thousands of them).  The sad reality is that it's not an easy ecosystem to jump into, especially at this point.  I would have expected the adoption of Kotlin to have come along with a renewed effort to draw new developers into the fold. 

When I finally got to the point that I had a working application, I looked back and realized that there actually wasn't a whole lot to building something simple, and potentially immediately useful.  It's just a matter of knowing where to look, what to use and how to navigate the common design patterns.  I wouldn't say that Android adheres to my understanding of a standard MVC pattern, but it's not too far off from that.  Google offers a handful of "starter" tutorials, that can be incredibly helpful but I also found to be a little bit incomplete.  I would have loved to have a cloneable repo.  There are a few generous souls that have offered turnkey projects for experimentation, in various states of currentness and working condition.  It's my hope that my little project offers a springboard to the curious. 

Where do we go from here?  I'm still not convinced that going the native route is best.  I plan on delving into React Native next.  Not only does React Native allow a somewhat agnostic approach to developing mobile apps, but it does so within the framework of React's familiar component-based design, using the tried-and-true JavaScript language.  I will report back with my findings. 

Until next time. 

Tuesday, April 7, 2020

Revisiting the Spring ecosystem

It's been quite a while since I posted last.  Between now and then, I've chiefly spent my time in the Node.js ecosystem, working primarily with GraphQL.  I'll post some insights about that experience later, but needless to say, it's been a very interesting ride.  Over the years, I've made sure to revisit the familiar waters of Spring and the JVM, but it wasn't until lately that I decided to take a deeper dive and see which trends were taking hold.  

I had long ago resigned myself to the reality that Groovy was likely on its way toward the great garbage collector in the sky.  I've had an eye on Kotlin since its inception, and was excited to see it gain a foothold as a first-class language for Android.  I've heard tell of it being adopted in organizations where Groovy had previously held favor.  And finally, Java itself has been evolving steadily, adding features both useful and baffling.  I mean, I still don't understand the purpose of "default implementations" on interfaces, unless the old commandment forbidding multiple inheritance was thrown out the window.

Spring, on the other hand, has only intensified its standing as the go-to JVM add-on, providing everything you could possibly need for about every scenario.  You can look back about 5 years on this blog to see me extolling the virtues of the ready-made JPA/rest combination.  During that interval, Spring has continued to evolve along with Java, while adding robust support for Kotlin and apparently continuing to support Groovy, which warms my heart.

As I dove in to the coding exercises we'll look at later in this installment, I was very interested in the Spring Initializr project.  There have been any number of ways to bootstrap projects over the years, from simply copying an existing project, to running lazybones to the current solution, which seems like a complete no-brainer, especially if you use IntelliJ.  



In addition to being able to choose between Maven and Gradle, you can select your language of choice.  Sure, Groovy is at the bottom of the list... but it's still there!  The real beauty of this process, however, is that it puts all of the available Spring libraries at your fingertips and picks out the necessary dependencies for you.  Mind you, this had already become exceedingly easy with Spring Boot, as those projects are mostly packaged as "starters" that aggregate all the necessary odds and ends. 



So, diving right into what I hope to accomplish with this installment of the blog: mainly, I wanted to get caught up on where things stand in Spring-land.  How easy is it to spin up a simple CRUD-enabled service layer?  And secondly, I wanted to compare and contrast the path of least resistance in all three of the Spring Initializr languages: Java, Kotlin and Groovy. 



So without further ado, here are links to the examples that I cooked up:


Kotlin

Kotlin is a relatively-new language.  When I first took a look at it, it seemed to me like it was an attempt by JetBrains (makers of IntelliJ, WebStorm and other excellent tools) to grab a chunk of Groovy's popularity.  The earliest iterations of the language copped most of Groovy's popular features, including the beloved "Elvis Operator."  After spending some hands-on time with the language, though, the differences between it and Groovy are many.  I could write a lot about the differences, but we'll save that for another time.  What you'll notice most about Kotlin is that, by design, it emphasizes null-safety.  So if a reference is allowed to be null, it needs to be called out like so: var foo: String?. Additionally, there's an emphasis on thinking about mutability.  Much like JavaScript's const/var nomenclature, Kotlin has val/var

Getting down to brass tacks with the example app I created, there are a few things to highlight.  One thing I found nice was how easy it was to mash multiple classes into a single .kt file.  Take the repositories for example:

Spring Data repositories can be defined in as little as a single line, as above.  Being able to combine them all into a single file makes a lot of sense in this scenario.  The same can be said of the shorthand for creating a class with fields: 


@Entity

class System(var name: String, @Id @GeneratedValue var id: Long? = null)  



In "plain old Java," this would take many more lines to accomplish.  In Groovy too, for that matter.   



One gotcha that you'll notice is the need for the lateinit var construct.  This is necessary for any injected properties and basically tells the compiler and its null safety policing mechanisms to chill out.  This isn't necessarily an indictment on Kotlin as a language, but speaks to the fact that they didn't have IoC/Dependency injection in mind when they started putting the language together.  



In conclusion, I don't really have too many criticisms around Kotlin as a language. Groovy is much more amenable to developers with a Java background, but Kotlin isn't exactly inaccessible.  It just has a tendency to be a little... different at times.  Any seasoned Java developer will agree that Maps can be an integral part of coding.  The authors of Groovy recognized this and made an excellent shorthand ([foo: 'bar']).  Kotlin has a top-level function toMap(..) and a to operator, which is still more succinct than Java (toMap("foo" to "bar")), though Java has made some inroads in that department in recent years.  We'll get to that later.  Lastly, I couldn't really figure out which way the wind was blowing vis-a-vis unit testing.  I did my examples with JUnit, which was easy enough, but kotest looks pretty cool and appears to be a very active project.   

Java

What can we say about good ol' Java that hasn't already been said?  In terms of sheer hours, I've spent the vast majority of my career writing Java.  I maintain that the language really lost its way when it added generics.  For my money, Java 1.4 was the pinnacle of the language as it was first envisioned.  It was unabashedly object-oriented, and balanced from the perspective of typing.  I understand why generics were added, but Sun's solution just didn't really do it for me.  With type erasure, a cavalier coder could end up in a heap of trouble.  The more recent addition of lambdas didn't bother me as much, though it really brings into question what Java is trying to be as a language.  OO?  Functional?  Or really, just the Frankenstein monster that I sometimes imagine it to be in my mind.

Anyhow, as far as the Java portion of this coding exercise goes, there are a few things I'd like to point out.  Since I'd stepped back from primarily doing Java and JVM work, a library by the name of Project Lombok emerged.  This has factored mightily into the Spring ecosystem from the looks of it, and I'll admit that it makes writing Java a lot less of an exercise in boilerplate coding.  The Groovy fanboy in me would question the need of such a thing when the problems have already been solved, though.  I suppose that it would be a way to get around the tedium of writing getters and setters all day in an organization that absolutely insisted upon code being written in Java (they exist).  In the Java code example I wrote, I mainly used the @Data annotation, which dynamically creates getters and setters, and adds a custom equals(), toString() and hashCode().  There is a lot more to Project Lombok than this.  It's really very cool, and employs some idiomatic trickery to accomplish some nifty things.  Bear in mind that you'll need a plugin for your IDE to make it play nicely. 

The other thing I'd like to touch on briefly is a feature that stormed in around Java 1.8: double brace expressions.  This makes working with things like Maps and Collections a bit less painful.  Here's a snippet from one of my tests:

new HashMap<String, String>() {{ put("projection", "fullTitle"); }}

In one line, I was able to accomplish what would have taken multiple statements before.  The shorthand here activates something similar to an anonymous inner class, and executes statements within the scope of the instance.  It's not as nice as the Groovy and Kotlin examples above, but it's certainly an improvement.

I also tossed in a Java lambda for good measure:

@Bean
ApplicationRunner loadTestData(EsrbRatingRepository esrbRatingRepository, 
SystemRepository systemRepository, TitleRepository titleRepository) {
   return (ApplicationArguments args) -> {
      EsrbRating rating = esrbRatingRepository.save(new EsrbRating("E", "Everyone"));
      System system = systemRepository.save(new System("Atari 2600"));      
      Title title1 = new Title(system, rating, "California Games");      
      Title title2 = new Title(system, rating, "Pitfall!");
      Title title3 = new Title(system, rating, "Tank Commander");
      titleRepository.save(title1);      
      titleRepository.save(title2);
      titleRepository.save(title3);   
  };
}

This just populates the H2 database with some sample data.  As you can see, it creates a bean, which is actually just a lambda that uses the outer scope from the factory method.  I'm still a bit iffy on the inclusion of lambdas in Java, when an anonymous Runnable worked just fine before.  But they certainly could have done it worse. 

Groovy

Ah, good old Groovy.  I spent a good many years in Spring/Groovy land, and jumping back in was like sliding on a well-worn glove.  I don't have a lot to highlight with this one, though I'd recommend lining it up with the Java project.  Even with the Lombok annotations, the superiority of Groovy shines through.  I acknowledge that it's purely a matter of opinion, but having started writing Java in the late '90s, I find Groovy to be a very thoughtful evolution of its principles.  One thing you'll notice is that I prefer to use a field/method/variable type on the left as opposed to def.  This is a purely opinionated move, and I prefer it over Kotlin which uses var/val, and requires looking to the right to determine the type (var id: Long? = null).  

I'd also like to point out how great the Spock framework is.  It has a minuscule learning curve and makes mocking a snap.  I can't say with any certainty how popular it still is, but it's clearly being maintained regularly.  The difficulty going forward is that it requires a separate spock-spring dependency to play well with all of Spring's testing apparatus, and I could see Spring starting to evolve faster than the potentially dwindling Groovy/Spock community.  I sort of hate to say it, but a huge part of my affinity for Groovy is how nicely Spock plugs into it.  Though Spock is also an excellent option for Java codebases as well.  I also looked at doing the Kotlin tests with Spock, but to "properly" test the code requires some odd-looking code. 

Spring

To wrap things up, I wanted to touch briefly on Spring and some of my observations coming out of this exercise.  Above all, I'm really flabbergasted at how awesome the framework continues to be.  It truly frees the developer from having to repeatedly churn out boilerplate code for common exercises.  spring-data-rest is my favorite example of this.  

Spring has really jumped on the HATEOAS/HAL bandwagon, which to me is a bit of a double-edged sword.  One of the challenges I immediately encountered in these examples was how to return immediately useful data to the client.  For a complex object representation (like most enterprise relational DBs), this means a ton of links.  Spring's solution to this is Projections, which allow you to expose a more fleshed-out object.  Without a projection, it would be up to the client to follow the links in order to have something fully-hydrated.  Even with Projections, there's no straightforward way to configure a default projection.  The projection has to be requested by the client as a parameter on the query string.  I can think of a handful of ways to hack around this limitation, but why should that be necessary?  

I haven't dug into the topic much, but I'm guessing there are lots of libraries in the JavaScript/native world that take care of navigating links and building full objects for the developer.  Even then, it seems to me that one HTTP request is better than a bunch of them.  It's worth noting that this isn't a problem for a proper NoSQL/document DB where everything is self-contained.  Food for thought.

Anyway, it was nice to be able to do this exercise and to get back to blogging.  I say this every time, but I hope to do more soon. Stay tuned. 

Sunday, November 5, 2017

Long Time, No Post

Since the last time I posted, a lot has changed.  I landed with a new client, I spent some time using some old platforms like Java and Spring 3.x.  I also got to experience a large company making a bold technical decision, eschewing the standard "enterprise" tools for cutting-edge platforms.  And that's partly what this post is about.  I was doing some work over the weekend (yeah, I know) and realized that I had stumbled upon something for which I could find no official documentation.  So I figured I'd do my part and put this out there, in case anybody is getting frustrated.  

Firstly, most people know that the Node.js community (and the JavaScript community at large) is extremely active, and that the technology is growing by leaps and bounds.  There are things like SQL Server drivers and integrations with nearly any platform/library you can think of.  I found myself needing to interface with a MySQL database (MySQL is actually pretty great, despite the fact that the evil empire now owns it) that was hosted on an environment restricted to SSH traffic.  Even connecting with a tool like Sequel Pro is a bit convoluted. So imagine my horror when I was faced with doing this programmatically.  Making things even more difficult was the fact that I was using "serverless" technology that could use a massive range of IP addresses, so simply opening the database port was not an option.

The way to achieve this was with a few absolutely awesome Node libraries and a bit of network-thinking.  First of all, if you aren't familiar with them, you should definitely checkout tunnel-ssh and ssh2.  The fact that some wonderful individuals crafted these libraries leaves me forever in their debt.  And then there's mysql, a great driver for Node.

So without further ado, here's how you do it:

const tunnel = require('tunnel-ssh');
const mysql = require('mysql')

const tunnelConfig = {
  username: 'user', // SSH User
  password: 'foobar', // SSH Password
 
  host: 'my.remotedbhost.net', // The SSH host, can be the same or different than the DB host
  port: 22, // SSH PORT

  dstHost: 'my.remotedbhost.net',
  dstPort: 3306, // MySQL port

  // This is where you connect to the database
  localHost: '127.0.0.1',
  localPort: 3307,

  privateKey: fs.readFileSync(path.join(process.cwd(), '/Users/foo/.ssh/mykey')),

  keepAlive: true
};

const val = 'foobar';
tunnel(tunnelConfig, (err, tunn) => {
  const conn = mysql.createConnection({host: '127.0.0.1', port: 3307});

  conn.connect(e => {
    conn.query(`SELECT * FROM foo WHERE bar = '${val}', (e, result) => { 
       console.log(`The value is ${result[0].foobar});
       conn.destroy();
       tunn.close();
    });
  });
}

This may seem rather simple at first, but there are a handful of gotchas here that I had to wade through before I found the promised land.  First off, the configuration for tunnel-ssh seems relatively finnicky.  The more information you provide about your connection, the better off you're going to be. Secondly, what you're seeing here is a much-simplified version of the actual program that I ended up writing.  There is a promisified version of the MySQL library out there, but it's much less popular and much less supported than the linked library, which relies upon callbacks.  I ended up in what I call "callback hell," where my functionality was borne out by a seemingly endless string of callbacks.  The more callbacks you have, the harder your code is going to be to read.  This is the reason that I prefer promises, especially via async/await.  Ultimately, you end up with code that performs in a similar fashion, but it's a lot more clear at a glance what it's doing:


const foo = async () => {
   const f = foo();
   const b = bar(f);
   await foobar(b);
}

Or...

  function foo() {
    return foo().then(r => {
      return bar(r);
    }).then)(r => {
      return foobar(r); 
    });
  }

But I digress.  There's another gotcha to consider.  When you're dealing with non-linear execution, you really have to bear in mind what the event loop has in its backlog and how it will behave as a result.  It is imperative that you properly handle any errors that arise.  Note that I didn't do that above, in hopes that it would make the code a bit easier to read.  Handling errors properly looks like so:


    conn.query(`SELECT * FROM foo WHERE bar = '${val}', (e, result) => {
       if (e) {
         console.error(e);
         conn.destroy();
         tunn.close(); 
       } else {
         console.log(`The value is ${result[0].foobar});
         conn.destroy();
         tunn.close();
       }
    });

Obviously there is some refactoring that should be done here, but you get the idea.  What you want to keep in mind is that your leftover event loop activity needs to be wrapped up or your program won't complete execution.  This was quite important for me, as the cost of serverless architecture is predicated upon how much time it takes to run your code.  If your code never exists, you can end up with an eye-popping bill at the end of the month.  With that being said, I highly recommend checking out Apex.  It makes managing your remote code and doing test execution runs all the more easy.

And since it's been so long since I've dropped a post here, I want to reiterate a crucial point vis-a-vis Node.js.  It's a great platform, but you need to make sure that you're using the right tool for the job.  I've seen too many situations where Node is seen as a hammer and everything is a nail.  Most of the time, if you're doing something database-related (like here), you'd be better-served using something like the JVM, where you've got a large pool of worker threads that can bombard the database simultaneously.  You'll really start to feel the constraints of single-threading in situations like this.


Wednesday, September 30, 2015

The non-technical side

Normally I can explain away a long absence by sheer laziness. Like anybody else, I slip into the grind and don't really feel like thinking about what I did at work once I slink home.  That's not the case this time, however.  At the time of my last post, I was at a very large retailer working on a sort of a "Skunkworks" project to improve the quality of a few aspects of its IT experience.  Though I was "technically" function in the role of a technical lead, I mainly developed software.  I was lucky enough to build up a highly democratic team, and with a project leader that didn't have much of an interest in all of the trappings of agile, we managed to get a very effective Kanban flow going and each did our turn in the leadership chair.  By this, I mean that the weighty "architecture" decisions and even ideas about how we could improve our day to day were completely democratized.  There wasn't an executive decision maker on the team, and things worked well.  Mind you, this was a team of very experienced, very agreeable developers, which isn't something that grows on trees.

Now, let's return to the "until recently" part of this post.  Though I was enjoying my stint at said large retailer, they decided to start going a different direction vis-a vis contractors.  I tested the waters and ended up finding an amazing opportunity right before the large retailer decided to extend me the extension I'd asked for.  Off I went to another, slightly less-large retailer.  In addition to being an altogether new technical challenge, the opportunity represented an extra set of responsibilities.  I spent a good deal of my time at my prior contract in a "people" role, figuring out how to make a team work better together, establishing effective procedure and sometimes, tearing down and restaffing teams.  I was tasked with doing a lot more of these "people" things at my new gig and a lot less straight "tech" stuff. 

Though I'm only a few weeks in, there are a few insights worth sharing about the transition and some of the things a technical person notices in this role.

You can't change everything overnight
I have to remind myself of this every day.  There are a lot of things that need fixing at my current gig.  From the lack of tests, to the waterfall-in-disguise "agile" process, to frequent micromanagement by developers.  These are all things that need to be fixed, but there's no better way to confuse, upset or anger your engineers than by shaking everything up at once.  Given, there probably are times where you could go "scorched earth" and roll an entire team over, but chances are you're going to need to maintain some existing software. And on that note...

Things are the way they are for a reason
Regardless of controlling one individual on a team may be, the status quo of a team is the result of a variety of factors.  If a team has delivered software, they've achieved some kind of success doing things the way they do.  As I mentioned above, I'm an advocate of the "unassigned and prioritized" backlog approach.  At my current gig, all tasks are pre-assigned during IPMs.  This made my blood boil at first (frankly, it still does) but I realized pretty quickly that the developers on the team weren't comfortable or capable of self-directing their work.  The only way the product team could get movement on tasks was to force them down to developers.

Leading by example goes a long way
This one is pretty simple.  If you want to earn a team's trust, the best way to do this is to be a part of the team.  When I was getting started, the expectation was that I was going to be a management "type," dictating terms and expressing my degrees of satisfaction from my ivory tower.  This has never really been my style.  I found that my team became a lot more comfortable with me when I embedded myself in the lab and did some programming.  Sadly, time is a precious commodity, and this it's sometimes difficult to find time to do this. 

There isn't one perfect way to do things
One thing I've noticed with my teams is that they do their best to "rigorously" follow the standard agile methodology.  Standups, user stories, iterations, IPMs, retros and so on.  Believe me, it's entirely possible to do these things and be completely non-agile.  If the team doesn't understand the purpose for the ceremony of agile, they're not going to glean the value of it.  When standups are becoming glorified status meetings, they should be cancelled.  When retros don't result in any tangible feedback and improvement, they should also be canned.  The whole purpose of agile is to be more effective in how work is completed.  Not every little part of it is going to work for everybody.  In fact, in my experience, I feel like trying to cram the trappings onto a team that doesn't understand them is a great way to get waterfall in disguise. 

Stay positive
There's always a light at the end of the tunnel.  Chances are, if you're not happy with the way things are going, you're not the only one.  Nobody wants to work around the clock, nobody wants to get beaten down by the business and similarly, nobody wants to be bored out of their minds.  If you start showing the right way to do things incrementally, chances are you can get some momentum in the right direction.  Also, it doesn't hurt to bring in some like-minded individuals. 

Wednesday, June 24, 2015

So you want to Mongo?

After a good 6 months of solid Mongo-ing, I think it's finally time to share some insights on the platform.  I can't remember if I shared my initial reasons for delving into Mongo, but the driving reason for moving on was a need to persist objects with a variety of nested properties.  Without exposing company secrets or boring you, it fit neatly into the problem we were trying to solve.  Imagine a standard table row with a varying degree of metadata underneath.  The standard way to do this in the SQL world is to have a secondary table that essentially serves as a key-value store (ironically, how some NoSQL databases store data).  Resulting access to the table would require a JOIN and things would get complicated when it was time to model your data out on the object/software end.  

After a lot of discussion amongst the team, we decided that the variable nature of the data (as well as the resulting oddness in data modeling) called for a change.  We had previously modeled our structure in PostgreSQL and the transition over to Mongo was pretty seamless.  The beauty of using Mongo for our specific platform was how it plugged into Spring.  Spring's Mongo support is absurdly easy and simple, and allowed us to store our metadata as a simple Map.  Mind you, there are most assuredly ways to do this with SQL databases as well, but Spring Mongo is perfect for this right out of the box. 

Anyway, let's get into some of the advantages and pitfalls of using Mongo and some reasons why you might want to consider it, and other reasons you may want to avoid it. 

Pro: Your data is best expressed as "documents," rather than "rows"

Mongo makes no qualms about being a "document store" rather than a traditional database.  What this means is that you store "collections" of JSON documents.  You can query these documents based upon facets of field values quite easily, with decent performance.  When you start to spread your data out across several collections, however, you're going to run into a wall.  The concept of a JOIN simply doesn't exist here, which leads us to...

Con: Your data structure changes frequently but your model can't

If you're going to use Mongo, you're going to need to be flexible on your modeling/software side.  Where SQL databases allow you to stitch new tables together with old tables via JOINs, this sort of thing can only be done in Mongo by doing discrete queries and stitching the data together in memory.  What you'll ultimately want to do is change the way your documents look, which often means subbing the type of data you store in specific fields -- this can be incredibly problematic for a system that doesn't allow for change at the same cadence and the database.  You should also be prepared to "sunset" some data as your structure changes. 

Pro: You don't like being a DBA

Mongo is incredibly easy to setup and administer.  Even doing things like sharding and replicating is a snap.  Additionally, Mongo's language of record is JavaScript, something that most of us are comfortable with.  There are a few domain-specific idiosyncrasies to learn, but beyond that, your confidence will build quickly.  You can also back your data up with ease.  I say this with a minor caveat: beware the "journal," especially if you're using things like database references.  Journal space can get absolutely enormous, and if your hard drive space is at a premium, this can bite you.

Con: You need to aggregate/summarize data

Don't be too alarmed.  Mongo has all of the summary functions you'd expect.  But prepare to have a bunch of JavaScript objects with nested objects expressing how you want to summarize your data.  If you're used to a nice, compact SQL statement followed by a GROUP BY, you're in for a rude awakening.  Once you start messing around with the aggregate(..) function, you'll gain a degree of familiarity.  This may or may not stop you from holding your nose as you write the code though.  

Pro: You aren't afraid of indexing for performance

When you're starting with Mongo on a small scale, you'll be suitably impressed with its performance.  Once you're dealing with tens or hundreds of millions of documents, you will notice a marked degradation in query performance.  The beauty of Mongo is that you can generally throw an index in and improve your performance to a spellbinding degree.  A protip is to use dex, a tool to automatically determine which fields could be indexed to increase your performance. 

Misc

There are a few tools you can use that will make your life incredibly easy.  I'm going to assume that you, like me, are a sane person and use a Mac in your development. 

Robomongo - My favorite Mongo querying tool.  The UI isn't much to look at, but it performs beautifully and is very query-friendly.  

MongoHub -  Another visual Mongo tool.  It brings nice UX to the table for certain operation but generally performs a bit more sluggishly and crashes in weird situations. 

Mongo Prefpane - A nice visual way to control your local MongoDB.  Another awesome aspect of Mongo is that it can be run locally with very little baggage.  You can also import and export data from a production or staging environment with ease.

Sunday, May 10, 2015

Jumping into Swift/iOS

I'd say that one of the most compelling things for lifetime software developers like me is the realm of mobile development.  Most of us spend the majority of our waking hours staring into the screens of our beloved mobile devices.  To deliver an app that would penetrate this world would be a huge contribution to this world, a way to get some great acclaim, and if you're very lucky, make a few bucks along the way. 

I've only just gotten started, but I figured I could give a look into some of the pitfalls a beginner might encounter.  The first, and perhaps most important, thing to consider is that you need to cough up $99 for the privilege of writing code on an iDevice.  This seems a bit asinine, but I guess it is what it is.  Everybody wants a piece of the pie in the Apple world, and they can get away with charging for the privilege of developing code for their ecosystem. 

The next thing to consider is the nature of that ecosystem.  I'd say the biggest hurdle to getting me into iOS development was the language.  Objective-C was (is) an unwieldy leviathan loaded with strange details and syntactic qualms.  Once i made the jump to Java, I never found myself missing the pointers and explicit references of yore.  Every time I'd get started on an app, I'd start writing code and end up so frustrated that I'd just abandon my project and move onto something less productive but more gratifying.  

Swift has really changed all of that.  It looks a lot like JavaScript or Python and does away with the old fashioned ceremony that plagued Objective-C.  The really good news is that Apple is reportedly stepping away from Objective-C completely.  This means that the entire ecosystem will be accessed via a shiny new language.  

Not all of this is wine and roses, though.  My first move was to procure a copy of AppCode, JetBrains' answer to the pitfalls of writing Objective-C (and Swift).  As I've said many times in the past, JetBrains is really the premier shop when it comes to delivering tools that make programming pleasant.  The refactoring is fast and seamless, and the UI is very intuitive.  My past experience with XCode, which is the stock Apple IDE, was a lot less friendly than I'd like.  Much like Objective-C, it feels like something from the '90s.  That or there are just a lot of assumptions built in to tailor to a long-suffering development community.  Either way, I figured this would all change with the installation of AppCode. 

There's good news and bad news to this.  The good news is that AppCode works just like IntelliJ.  It's a great tool  as one would expect.  There's the full complement of refactoring tools and the lovely Darcula color theme.  It's also got an integrated UI composer, which is relatively new.  The good news, unfortunately, sort of ends there.  I'm guessing this is just a side-effect of Apple having a "closed" ecosystem, but AppCode can't function without XCode.  My initial take is that it taps into it for things like the UI composer and the other settings that it needs to operate.  

Where things start to get cool, however, is when you can have a barebones app running on your phone within seconds.  To get there, however, you have to register your device on Apple's developer site.  And then you need to refresh your XCode configuration.  Then you're good to go.  

I'll do my best to document my (mis)adventures as I get my first app out into the App Store.  The app is a simple thing that will allow bee-minded folks (like yours truly) to document where bees are seen feeding.  All it will really do is upload a photo and allow fellow bee-minded folk to view the sort of plants that bees seem to like.  It's not very sexy, but it's an idea. 

I do apologize for my long absence.  It's been a pretty eventful few months, filled with more Groovy shenanigans, a lot of fun with Mongo and some nodeJS too.  I'll try to get into some of those exciting topics soon. 

Sunday, February 1, 2015

The Holidays are Over



Well, the holidays as we know them are officially over.  Somebody in Scottsdale is sweeping up red, white and blue confetti and many people are sobbing into their beers in Seattle.  With that, we enter the cold months of winter.  The months where football-obsessed software guys like me can finally achieve a sense of clarity and take up the pet projects that got no love during the nail-biting weekends. 

A few things to stay tuned for -- a look at the advantages of AngularJS and single-page applications (SPAs to the initiated).  

And (probably) more excitingly, a look at mobile development as I undertake a few apps that have been clanging around in my head for some months.  As well as a quick glance at the Swift language -- something that's actually got me excited about writing an app for iOS. 

Also, after a few months of working with a new team in my primary development endeavors, I have some thoughts on pragmatic automated testing... be it unit, integration, functional or otherwise.