How We Make Trello(blog.fogcreek.com) |
How We Make Trello(blog.fogcreek.com) |
What's missing in this article is the whole Continuous Delivery technical aspect of it.
What do you guys use to build the NodeJS app?
What do you guys use to test the NodeJS app?
What do you guys use to check the code coverage of the NodeJS app?
What do you guys use to test the front-end?
What is the automated testing strategy?
How do you store artifacts of builds, schema migration (if using RDBMS) or handle different model versions, how do you rollback (what's the rollback strategy)?
NodeJS community (and to some extend, the RDBMS/NoSQL crowd that wonder how to support different version of the model) would probably learn greatly from that type of article.
disclaimer: my entire life is run via trello.
In my opinion if there's one thing a reader should take away from this it should be that Single Page Apps and separation of server and client are The. Best. Thing. Ever. From the start, design your system this way.
Good post, and an entertaining read.
Funny how that works, huh? A lesson many, many other companies could profit from.
Lesson learned - creating a community or following of people (i.e. talent marketing) is a very powerful thing.
A very counter-intuitive result: most people would not consider a stable API to let you iterate quickly!
All that said, I think that letting every developer deploy would not be a bad idea at all. The problem is that our team is too big to do that without creating more robust deployment tools and too small to dedicate enough time to doing so. My hope is that one day we can get there, though.
Need it for compliance documentation.
The no bugs claim indicates to me this wasn't written by a technical person. Or at least, not very technical.
I love the separation of concerns that is possible with JS apps - you can have one team working on the API and one on the interface and the only place they really need to communicate is in the API documentation. Once it's all done, you've already got a fully functional and secure API (because it wasn't an afterthought) that can be used for other clients.
> I love the separation of concerns that is possible with ... one team working on the API and one on the interface
That is, in my opinion, the larger point. If you can do solid 'interface driven design' then you enable rapid evolution on both sides of the API. One of the things Jon Wall and I did at NetApp was prototype a better split of system across the RAID and Filesystem layers, that split achieved 50% better performance across the same spindles and it allowed for innovation in the file system layer that was currently hindered by "all the hooks into the RAID stuff".The key though is picking the right layering, and not having too many. Like hashes in perl you can go crazy and suddenly everything is an API and simple things go through n layers and bog down.
When people tell me they want to be architects I ask them questions about layering, that is where you separate the good systems thinkers from the not so good ones.
Yeah, me too. Apart from the actual, observable benefits you mentioned, I just find something really satisfying about the separation. Fewer hacks, easier to modify things.
I think the rise in the popularity of doing things this way is largely thanks to the increase in popularity of test-driven development. Creating a client app without an API is so easy given all the tools available for mocking or faking APIs, and creating a standalone API is easy given that most of the time, you're just testing the JSON or XML output of a bunch of functions.
That's already how you should be working anyways. Unfortunately, most language don't seem to have support for a decent template system that makes this natural. People need to start making heist clones in their language of choice so doing things right becomes more common.
Those are two orthogonal things. All my sites have a complete separation of presentation from code and access a nice API to get data. Including the ones that are purely HTML and have no javascript at all.
Single page apps are good for things that are actually apps. Except that I want to leave the app open, and several other apps, and not have it interfere with my normal browsing. Until browsers realize this, it is actually pretty irritating to use browser apps.
That said, I agree that making something into a single page app just to get this separation isn't going to be useful.
If you can build some kind of SaaS Android CI system, you'd probably make heaps of cash. Android CI is just enough of a pain to do yourself that people would pay for a one click type solution.
With Git, you have a working _repository_ with changes and then you do "git pull", and Git merges the upstream changes into your repository.
From the user's perspective, it looks about the same. But the Git merges are safer than the Subversion updates, because if the Subversion update messes up your working copy, you're stuck. But with Git, you always have (1) the commits you made locally, (2) the commits you just pulled from upstream, (3) the merge that was done by "git pull". And (1) and (2) can't get messed up, only (3) can get messed up. But you still have both your version (1) and their version (2) to go back to, so you have lots of chances to fix it.
Think of Git branches and the corresponding merges to be like Subversion updates with backups of the previous local working copy.
Which is a practice I got into the habit of doing manually when I used to work with Subversion.
This saves us some merging.
With github it is especially nice. I push to a remote branch, which I can see when I go to the project page. When I click merge it shows whether or not the TravisCI build passed. If it looks good, then I click to auto-merge and it's all set. It is possible to even automate away that part as well and have the whole thing merge and deploy on push if the build passes, but I am not quite ready to take the plunge yet with that (too easy to botch a production release IMHO).
It's a nice workflow, changes are very visible to the entire team and well summarized (by the commit history and any comments/discussion on the pull request itself). Making a new branch is a one-line operation (two if you count hooking it up to the remote), so no, I've never personally felt that was a drag. Sometimes it feels a bit silly to create a branch for a one or two line fix, but the visibility to the team is worth it.
I love trello... but I don't like the branching model... :)
This workflow won't work without automated tests... is lack of automated testing the reason to have individual branches for features and bug fixes?
Basically, we have many clients that are consuming the API, including our mobile apps. We never change the published interface so that if you're getting some board fields that will always work. This means that we don't change the types of fields (for example string vs object) or the names of fields since that changes the published service contract.
What we do instead is add more fields. A very good example of this is emoji. We added emoji support a while back and instead of changing the "text" fields to be objects or embedding HTML (gah) into them we added another field called "textData" that has the extra info.
This is copy/pasted from an actual call for getting card actions:
"textData": {
"emoji": {
"daft": "https://trello-emoji.s3.amazonaws.com/4f820a995a03e8e82d134ac4/ae846ca70bf7aa95dd3330b8fd1c70cb/art-daft-punk-steampunk-951631.gif"
}
},
"text": "Custom emoji! :daft:"
This may not be sustainable in the long term and if it's not we'll version the API if we have to at that point. So far though, the API has proven itself to be very well designed and adaptable (thanks to @d_lec)We use gradle for building. The actual app is split into two, trello-app and trello-lib. Anything that can be done w/o Android like SQLite caching, API calls, etc., is done in trello-lib which is a plain Java library. It makes the dev cycle much faster since you can write a unit test and run it in a second.
We don't have CI setup yet. For the server we use something custom but will most likely be moving to Buildbot and with that we'll also setup Android CI.
> The revelation could result in a rippling shockwave that knocks you off your seat and may have troubling, unpredictable consequences for the time-space continuum. Possibly.
> You’ve probably downloaded our iOS, Android, Kindle, and/or Windows 8 apps, and are saying to yourself, “These are very well polished apps which I have rated or will rate favorably in their respective app stores
> The Trello API is well-written, has no bugs, and is totally rock solid. Or at least it doesn’t change very often. [Goes on to only reference the fact that it doesn't change very often]
The web client (trello.com) has a cookie that has the auth information. The actual code executed for both examples is identical.
Btw... I am trying to get some teams in my company to get out of branching. So trying to understand your view (which is exactly what these teams are doing), hence these questions...
- Have sensible working hours (30 to 40 hours a week is optimal).
- Either let people work from home, or give them private offices.
- Don't have idiotic hiring criteria like buzzword matching or college degrees. (Meta: don't have the personnel department doing the hiring.)
- Get at least the basics of tools and process right. You don't have to let people code in Lisp or Haskell, but when a candidate asks you about version control, the answer better hadn't be "oh we don't have time for that here".
- If you are requiring people to work in the office, don't quibble about things like high-spec machines and good chairs that cost a small fraction of the cost of hiring people.
Hit everything on that checklist and even if you're still not quite as sought after as Fog Creek, you'll be well out in front of most of your competitors at little cost in either time or money (and infinitely far in front of Fog Creek for any candidates who won't or can't live in New York).
Fog Creek actually hires remote people now. We made the change almost a year ago and its been a great source of new candidates.
I still dont get it why people keep thinking that to cram puzzlers on a noisy heap with all possible (social, visual, audio) distractions saves money in the end. If Joel can offer programmers sane working conditions in NY, so can every office around the world.
You can have a front-end web server that is also a client of the API server and keep the separation as if it were any other API client. This is the approach I'm taking in my current project since I have to support some obsolete browsers, but more generally it lends itself to a cleaner decoupled architecture
It's not only possible, it's pretty trivial in most cases. Just endow each user facing object with a .ToHTML() and .ToJSON().
This is actually one of the core benefits of REST, you send me a request for a resource along with some desired media type(s), and I send you back a representation in the media type of your choice (or as close as possible).
The trap a lot of developers fall into is going around the existing API for server-side applications though, thinking they'll get more performance by (for example) going directly to the persistence layer. That's how most server-side apps are written, actually; api and front-end tightly coupled.
I agree, but there are other benefits too :)
Yes it is, that's my point. Our designers push new templates and our developers push new binaries completely independently. We literally have an API doc that the designers put "I want this" into, and the developers implement it and update the doc to reflect it being finished. People just use template systems that make this unnatural. See heist for an example of a system that makes it natural and straight forward.