Don’t Make Me Think, When I Consume Your API

I recently worked on the voucher badge feature.  I needed to create an api endpoint to consume the voucher count, because we use services.

Unused Voucher Badge
The first iteration, the api passed voucher objects. However, I decided to refactor and pass the voucher count and less data between services, in hopes to shave couple milliseconds off load time. My first refactor looked like the following. Looking at the code, I know exactly what is happening and what data is being passed. It’s simple. 
unused voucher count as integer
Now imagine you’re consuming this new endpoint for the first time, with no knowledge of the implementation. You receive the following json object.  You might think, “Seven? what the hell does seven mean?” Then you’ll inevitably follow the source to VoucherController in order to understand.   

Instead, why not be explicit? Make it clear to everyone who consumes your lovely api what their getting back.

unused voucher count as a hash

That is so much better! Now I don’t have to visit the Api and look at the source code in order to understand what the object is.

So why not make others happy by telling them what their consuming, instead of making them think. Make your api intention explicit!
[EDIT]

Lets take this one step further and change our controller name as well. To be clear the vouchers controller only had one job of grabbing all unused voucher and returning the count. If it was part of a larger vouchers controller, I would have refactor it out instead .


Not only are we explicit with the object that is being returned, but the API name. I think this gives a better explanation of the api.

This post was based on a lightning talk I planned on giving at RubyConf 2014. However, the talks were cut short so I decided to make a blog post about it instead.

Standard

Using Ruby memoization

In a service oriented architecture we make many requests to external services. These requests time adds up and slows down the site. To improve our performance I can use the memoization technique to make our pages faster.

memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

When I program I memoize by setting an instance variable to a request.

  1. @foo || = bar.new(params)

This makes a request once, then sets the value to @foo. This persists as long as the instance of the class.

Recently I faced a problem where a method was being called twice. We’ll call it external_request? method. I pass in foo and bar, then check to see if it returns true. The issue was the method was being called twice. The first call returned true, but the second call would return false.


  1. def external_request?(foo, bar)
  2.     @foo = foo
  3.     @bar = bar
  4.     @foo && @bar
  5. end

 Because I care about the first call I knew I could solve this by memoizing the values.

  1. def external_request?(foo, bar)
  2.     @foo ||= foo
  3.     @bar ||= bar
  4.     @foo && @bar
  5. end

This returned true even after the second call, because I saved the value into the instance variable.  Now something to keep in mind. When you are using this technique you want to be careful not to memoize a class variable.

The danger is that this class variable is shared between all users who are on the same instance(unicorn, dyno, etc). Can you see the problem there? If user A makes a request and returns true, then every time the method is called this will return true even if it should be false for other users. This will persist until the unicorn is switched or we refresh the server.

How did I solve the above problem? By making a new method that calls external_request? and sets a cookie during the first method call.

  1. def make_request
  2.   if self.external_request?(foo, bar)
  3.     cookie[:external_request] = 1
  4.   else
  5.     true
  6.   end
  7. end
  8. def self.external_request?(foo, bar)
  9.   foo && bar
  10. end

The lesson is that memoization is great for performance, but we need to be careful what we memoize. In almost every case you don’t want to memoize the class.

This post was inspired by Jon Phillips.

Standard

Refactoring And Building The Next Big Thing

Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior


Refactoring is important and necessary, but many times it gets pushed to the backlog. I want to make three point with this post. Why refactoring isn’t taken seriously. When to refactor. And changing refactoring habits. 

As developers, we are paid to build features and fix bugs to increase value for customers. From the project managers point of view, refactoring does neither one of them. So we can say that refactoring is for the developer. This realization gives us insights to why the time allocated to refactor, is so minimally. The PM’s would rather see new feature and bug fixed instead. Code doesn’t get refactored. We keep digging the hole deeper and deeper.


So when should we refactor? If we’re constantly swamped with tickets from our PM we’ll never have time to refactor. The solution? If we’re not given adequate time, we need to refactor in small batches. Tickets should be completed along side small incremental refactoring. This helps us release features reasonably and fix parts of the code. These little batches are now easier to work with and speeds up development time. These refactoring should be within the files we are currently working in. We shouldn’t go out of scope. This will keep us grounded to meet our deadlines.

These are some habits I have learned throughout out the months (1 year in November; Yay!). First following the TDD way (red, green, refactor). As a professional this didn’t fit our team’s agile approach. We refactor but test doesn’t drive our design. Next refactoring in chunks. Asking for time to refactor and going through our codebase to clean up dead code and smelly implementations. To be honest, this doesn’t happen to often. There is little time. So we end up having a larger than necessary codebase with dirty implementations.

I recently began refactoring while creating features and it’s been going great. I’m still not satisfied with the codebase, but I see little win’s over the map. This makes me happy as a developer. 

Credits goes to Ronald Jeffries, 3 founders of the Extreme Programming (XP), for inspiring me to think of refactoring in a different light. His original blog post can be found here: http://xprogramming.com/articles/refactoring-not-on-the-backlog/

Standard

Learning How Startups Leverage Technology (DC Tech Meetup #30)

I attended the DC Tech Meetup #30 where I got the opportunity to listen and watch many different startups pitch and demos. The coolest thing for me was to see how these startups were leveraging technology to bring value to this world. I’ll go through each startup and explain what they do and share my thoughts about them.

Demo 1: Aspire (Neil Shah & William Huster)  – I missed this presentation

Demo 2: ID.me New Product Launch! (Blake Hall)

Idea – Verify people’s identity (teacher, military, student, etc) virtually.
Tech – Seems like a difficult problem to solve. Need multiple layers of clearance from the companies side and other agencies. Depending who is requesting information about the individual, they unlock multi-layer security. If it’s a higher security, then the software needs to receive a higher clearance more data to verify the user.

Overall(1-5): This idea is a note worthy 5. The team has proven that a pain point exist by reaching out to *retailers and other agencies that require identification clearance. They have built relationships with multiple different industry to leverage their technology.

*Retailers currently don’t give out discounts online, due to higher fraudulent claims. This is solved by Id.Me

Demo 4: Framebridge (Julia Lovett – julia@framebridge.com) 

Idea – Create custom frames that you’ll love

Tech – Mobile App that allows users to pick out a custom picture frame (with various sizes, colors, and patterns) with a feature to test out how it would look on your wall. Not complicated program. Straight forward main platform an section to choose in-stock frames.

Overall(1-5): Not the next million dollar idea, but definitely have potential. It’s a solid 2. It’s working in a highly niche market so it’s easier to target, but I don’t see how they can grow beyond the niche market. 

Demo 5: Vouched (Keith Cooperman)

Idea – LinkedIn like feature where users rate each other’s characteristics to see if they would be a good fit for a company.
Tech – A connection to users linkedIn profile, then leverage their contacts to rate others character traits. Manage multiple database table to store each users ratings, their average, and their contacts. Lot of different database involved to organize users feeds, ratings and information employees finds useful.

Overall(1-5): I’m personally very skeptical about this idea, because I don’t see any added value. It’s going to be hard to convince people that they need to rate their “friends” or “sort of friends” personality. First off why would I waste my time doing this (when I don’t even recommend skills sets of others). Second what is the different between endorsement in LinkedIn and this product?

Demo 6: Openreporter (Misha Vinokur – misha@openreporter.org)

Idea – Allow regular joe’s to report any noteworthy news to certified reporters.
Tech – Two different home page for regular joe’s and reporters. Regular joe’s needs to be able to post the situation. Both users need to communicate via comments on reports the regular joe’s make. Each report is pinned on a google map.

Overall(1-5): Overall it’s a solid 2. It’s an interesting idea, and innovative. However, I’m not sure how many reporters would want to quote a random guy who claiming “Dude I just saw t-rex riding on a elephant with a cow boy hat. It was awesome!” It’ll be bad journalism if they simply believed what people are saying. I want (video) proof. Second I guess they’ll charge reporters for this service or ads? Don’t see reporters actually paying initially (chicken and egg problem).   

Demo 7: AgSquared (Jeff Gordon)

Idea – Organize data about individual farmers crop type, yield, harvest, etc to analyze farmers data over the years to help them make informed decisions in future harvest/investments. There are sensors in place within the farm that collects data as well.
Tech – Probably the second hardest to implement after Id.Me. They use tracking within the farm and display the data through a graph on the farmers dashboard. The software analyzes the data (in ways the founder didn’t go into) for farmers to use.

Overall(1-5): I give them a 3 for two main reasons. The idea is relatively innovative and very useful for farmers in the long run. The negative is it’s very time consuming for farmers to actually input all the necessary data to make this useful. This takes time to learn to use the technology and take time out of actually labor.

Standard

How To Have Effectively Code Reviews

Code reviews can be a daunting challenge for developers. It’s hard to know what to look for in a given pull request (PR). I want to share some tips that I have learned from other LivingSocial engineers.

Questions you should be asking about the PR

  1. Do you understand what the PR does?
    • Does it have a clear commit message?
  2. Do you understand how the code accomplishes the goal?
  3. Is the new code tested? 
    • If it’s a big new feature, is it covering edge cases?
  4. Does the code use obscure syntax, how could it be more clear or less obscure? 

Must Do

  1. Does the entire test suite code pass?
    • Run the full test suite, and not only the one controller that changes
  2. Pull down and rebase so that your newest commit is on top
    • This way if you need to rollback your commit, you don’t have to shift through multiple commits to get to yours
  3. Worst case scenario back up plan
    • If all goes to shits, what are the steps the merger should take to undo this shenanigans
  4. Don’t dilly dally when you see a PR. Be as responsive as you can in order to have an effective feedback loop. 

This is a good start for effective code reviews and merging pull requests. These steps have helped us find bugs, code smells, and fast cycles for a better engineering experience. 

If your team has other methods for effective code reviews, please share down below.
Cheers!
John  

 

Standard

5 Mistakes That Junior Programmers Make

As a young developer, I had the opportunity to make mistakes, some costly and some not so much. And I have no doubt I will continue to have many more opportunities in the future.

Here are my top five rookies mistakes that I’ve made in the past half a year.

  1.  Not being decisive with my code. As a rookie on the team, it’s nerve recking to display your work. It’s similar to practicing violin for hours after hours (8th grade until I graduated high school), but still being afraid to perform in front of the teacher. I try to delay it as long as possible. This was not a good idea. I ended having longer review cycles. The problems in my code would have surfaced sooner, if I reached out to my tech lead sooner. Advice: get a second eye on your code as soon as possible
  2. Working only within the boundary. I tried to fit my code within the models and controllers that are available. Having to work with the Accounts service, I wanted to fit this aspect in the closest javascript file. This led me to the application.js (the all knowing) file. However, talking with other programmers it made sense to create it’s own accounts.js file. I handicapped myself by creating an imaginary boundary line. Advice: talk to another developer and get feedback on your implementation
  3. Git issue. Merging Conflicts. As my first programming job, I wasn’t too familiar using git with in a team. I made awful decisions of pushing without pulling, pushing without running the full test suite, and creating merging conflicts. Those are the worst. Advice: after you commit. Git pull –rebase origin master. Run tests, then push. By rebasing you’re putting your newest commit on top of the latest master. 
  4. Not specifying order of commit. I created two separate pull requests in two different services. I did not specify that PR 1 is contingent to PR 2. Then PR 1 was reviewed first and got merged in. This created issues as the PR 1 tried to make ajax requests that PR 2 was suppose to create. Advice: Always notify in the PR if it needs another PR to be merged in before hand. 
  5. Lack of defensive code. First time Redis user. I didn’t think that Redis would ever go down. Didn’t put in a rescue clause when Redis service goes down. This caused my app to break. Advice: Get in the habit of writing defensive code against potential issues.  

Let me know what mistakes that helped you grow as a developer!
John

Standard

Dead Code Is Dead Code

As a programmer you’re going to come across code that are residue of dead features. You need to figure out what you are going to do with the mess. Are you going to delete it or leave it?

You have several options.

 Door #1. Exterminate dead code. The idea is that you’re not going to use it anytime in the near future and it’s taking up space. So you delete it.

  • Key Benefits
    • Less lines of code, less problems
    • Easier to navigate through your code base. No need to scan through code thinking if it’s in use or not 
    • No dead code laying around
    • IF you wrote tests for these, you’re test suite will be reduced
Door #2. Walking Dead. Let it be in the codebase because it’s not doing anyone harm. The possibility of brining the code back for a different feature
  • Key Benefits
    • This is only true if you know the time line you’re going to reuse the code
    • Saves time implementing the feature as you have a pieces of the feature or all of the feature ready with this old code 
Door #3. Give up. This world is too harsh for you to bear. 
  • Dead

I’m going to make couple assumptions. You use tools like Git, or Mercury. Less lines of code (LOC) makes codebase easier to read. Less time it takes to run the test suite the better. With these assumptions the benefits of door #1 far outweighs those of door 2.

The only benefit door 2 has is if you’re team decided to reuse the code soon.

However, this is also possible in door 1. When you use a subversion tool you’re writing commit messages with your changes to quickly notify others what you did.

git commit -m ‘Removing daily mush feature as it is not being used anywhere in the project. This feature allowed us to deliver coupon to users emails’

Now that you have a good commit message to reference to. In the future if you need to see what that commit did (what methods you deleted), you’ll grep through the logs and find your old commit.

git log --all --grep='daily mush'

Now you’re free of dead code and you’re able to revert back to the original state if it comes down to it.

Leave a comment and let me know what you think!
John

Standard