I started this month by speaking or hosting at 4 events in 2 countries over 5 days (DrupalCon Amsterdam, DomCode, ZgPHP, WebCamp). While hectic, it was a great way to see a cross section of the community back-to-back. So, I’d like to talk about the events in turn but also some meta-topics about conferences themselves.

DrupalCon

This was one of the biggest conferences I’ve been to, and definitely the slickest, most well produced. Huge stages, a giant conference center, a “pre-note” with zebra pattern suits and super heroes. The conference had a good sense of humor about itself but the ambition was evident. Drupal is Big(tm) and they know it.

From a tech and community perspective, it’s an interesting position. On the one hand, Drupal began life as a open-source project but now has a massive commercial side (check out the sponsors hall). The keynote discussed Drupal as becoming a Public Good, citing Paul Samuelson’s work and outlining a 3 step lifecycle in this process: Volunteers → Business → Government. The fact the keynote began with a sponsored doppelganger act was a tacit admission of where Drupal currently stands in this process.

This isn’t necessarily bad. I have little knowledge of Drupal but my impression is the commercial interest helps drive an increasing “professionalization” of the developers and tooling. Rolling out best practices and applying general engineering principles to Drupal is a great step forward. Make no mistake, they are tackling genuinely hard problems.

Perhaps for this reason, Drupal is also trying to reconnect to the PHP community at large. This is also a hugely positive (and arguably necessary) move to bring in some of those professional dev practices. At the same time, the feedback I received for my talk on the general PHP track was different enough from other conferences to remind that it is a separate audience, at least for now.

Still, the question on everyone’s mind was “How do we keep hobbyist developers?” I interpreted this as: “Has the re-engineering of Drupal made it so complex that only experienced pro developers can reasonably work with it and was it worth the additional complexity?” To that: I don’t know. I don’t know the code. A well engineered codebase should be less complex but using it may require you to sideload a lot of knowledge (i.e. indirect complexity). That’s possibly a culture or documentation issue, not a technical one.

Some of the articles in the Drupal magazine I found in my swag bag questioned if this was even an issue. Perhaps the natural evolution of Drupal is a focus on high-end, high-traffic CMS sites. Perhaps not.

Either way, it was a great conference. Drupal is juggernaut and here to stay. I don’t know where the road will take them but they’re trying to head in the right direction, even when it’s uphill. Much respect.

ZgPHP

Two days later, and I was presenting at ZgPHP in Zagreb, Croatia (my first trip to the region). The difference was intense.

ZgPHP is a local user group in Zagreb and this was their second annual conference but their first in English. As such, it’s a much smaller event: Total attendees were around 80, though the number waxed and waned throughout the day.

One of the great things about this conference though is the price: it’s completely free to attend. Like DrupalCon, ZgPHP is also worried about the hobbyists and the lone cowboy coders and the tiny dev shops. So, their response is to lower the barrier to obtaining pro-level knowledge, at least as much as possible and free tickets are a great step to do that in a country where the unemployment rate is a crushing 20%. They can’t reach everyone with this tactic but it’s certainly not for lack of trying.

To be fair, that comes with certain tradeoffs: The venue was donated by the local Chamber of Commerce. There was no catering staff and lunch was local pastries with 2 liter bottles of Coke. My badge was an oversized sticker with my name and twitter handle written on it in marker. (When I returned to the hotel, I peeled the sticker off carefully and cut up toilet paper with shaving scissors then stuck to the back so I could bring it home for my badge collection).

So, yes, it’s a small conference but by design. It was well run, well organized and a really nice community.

Croatia isn’t a huge country (4.23 million people, slightly less than Kentucky). Nonetheless, there’s multiple user groups and even another annual conference. That’s some great hustle. By and large, the conversations I had were the same as anywhere else: HHVM and REST APIs, unit testing and decoupling. I was the only speaker not from the region, which made me nervous but folks laughed at my jokes and left nice joind.in reviews. It was a good crowd and I had fun.

WebCamp

Two days later and I was at another conference in Zagreb: WebCamp. Rather than focus on any specific language or tool, WebCamp is about, well, the web.

It’s also massive. And free. Like ZgPHP, WebCamp is totally free to attend. All you had to do is register for one of the 1100+ free tickets on their website, which lasted less than a day. Of course, as with any free ticket, there were a lot of no-shows but around 800 people attended on the first day. True, that’s smaller than DrupalCon but 800 people is significantly larger than almost any PHP conference out there.

Still, a conference of this scale has bills, so attendees could buy a supporter pack (~40 euros?), which came with a t-shirt and some other goodies. Lots of sponsors chipped in and they received perks like evening stands and an hour-long recruitment session on the first day.

WebCamp was a joint effort by several local user groups: PHP, Ruby, Python, JS, you name it. In fact, WebCamp and ZgPHP were part of a whole initiative called “Week of WebCamp” where there were several smaller conferences and workshops throughout the city of Zagreb.

It’s an ambitious undertaking which culminated in WebCamp itself. I’m don’t know if any of the individual groups could’ve pulled this together individually but together, they made it work really well. I saw talks on everything from Elixir to Gearman to data aggregation.

For my part, I was asked to do the opening keynote, which was an enormous honor but the size made it intimidating. Still, the crowd laughed and had fun and even I was reasonably pleased with the result. They also asked me to host one of the tracks which meant a crash course in pronouncing Crotian names (final score: D+).

I’m a huge fan of multi-technology events and also the free-to-attend model but they’re hard to get right. Watching someone pull off a 2-day, dual-track, 800 person conference in those formats plus the additional events throughout the week was amazing. Yes, nothing is perfect but it was absolutely a success.

I’m not an “Everything is awesome”, “Community Works” cheerleader sort of fellow. Still, WebCamp in action was inspiring and leaves me wondering if it’s a taste of things to come: a free-to-attend, multi-community event supported by donations and sponsors.

Conclusion

I had a great time at all of the events and would highly recommend any of them (I skipped over DomCode as I’m one of the founders but would highly recommend it as well)!

Still, I left with a lot of questions. Everywhere I went, people mentioned hobbyist or junior developers. How do we reach them? How do we attract them? What do we teach them? This is especially true in the PHP community where there’s a huge variation in knowledge level.

It also left me wondering about the role of those teaching. Are free-to-attend events more open? Doesn’t that leave us more dependent on our sponsors? Should our conferences be more cost-effective affairs or can we teach more effectively when we go all out? Is commercial backing driving knowledge or impeding it? How can we encourage the right attitude in our partners? Who are we really targeting with technical conferences? Is turning teaching into a commercial interest an acceptable path for an open source community? What are the role of speakers in this?

Each of these events brings a different model to the table. Is there a right one? Well, the fact that all of them are successful in different ways says probably not. I loved the variety of speakers plus the pomp and circumstance of DrupalCon but you probably couldn’t pull that off on a ZgPHP budget. At the same time, I felt like I could take more specific questions and help people more deeply at ZgPHP precisely because it so direct. There are things you can do with one model that you can’t necessarily do with another. I suppose we need different events pushing different models to catch the widest possible subset of the community, though I wish we could do better.

One amazing thing was that all of these conferences were recording their talks to publish them on the web for free. My DrupalCon talk was online less than 2 hours after I gave it, which is bonkers. Perhaps the web-based model is the real future here, though as long as there’s a hallway track and a social to network at, there will be value in attending conferences. Which just leaves one question an event to consider: who are we trying to bring in and how do we get them there?

Many thanks to Igor Wiedler for proofreading an earlier version of this article

Earlier this evening, I was a guest on NoCapes, a new web series about sharing advice and encouraging folks to engage in the PHP community. It’s a great initiative, you should check it out. There’s also a video of my interview up as well.

But as we begin The Autumn of a Thousand Conferences, I thought I’d follow up by taking a moment and write up some tips on speaking. Bear in mind, I only began a couple years ago so this is just what works for me. I try to focus on the more practical and less glamorous bits of the speaking experience so you know what to expect.

Ultimately, the #1 rule is this: speakers are the same as any other type of performer. It isn’t about talent, it isn’t about luck, it’s about work and practice. So, don’t beat yourself up if you’re not amazing at first and don’t expect to be well respected until you pay your dues.

I would also ask yourself what is more important. Personally, I’d rather be known for being a good engineer than a great speaker. That said, speaking has helped me make some amazing friends and grown my career considerably. You can (and probably should) try it as well.

Getting Accepted

  • It’s cliché but start off small: user groups, local meetups, etc. When submitting to a bigger conference, mention your experience. Include links to joind.in, reviews, etc.
  • Just like any type of writing, you’re going to get rejected. A lot. Even when you’ve got some talks under your belt, you’re still going to get rejected on a regular basis.
  • If you have no recorded experience, a 2 minute demo of you covering a small topic can make a huge difference. Many conferences are trying to add new speakers but they’re also risk adverse, so show that you know your stuff.
  • If you’re submitting to a conference that requires traveling, always submit multiple talks (at least 3, maybe more). If they’re going to pay for a flight and hotel, they’re probably going to want 2 or more talks from you.
  • If you’re attending a conference you’d like to speak at, rock it hard at the uncon and then tell the organizers you’re going to submit next year. They’ll remember you. Some conferences even give away guaranteed speaker slots to the best uncon speakers of the year.
  • It’s perfectly okay to submit talks you haven’t written yet, provided you have time to write them. Shoot in a few ideas and let the organizers sort out which ones are good. Likewise, don’t be afraid to reuse talks at other conferences.
  • It’s okay to pick subjects you need to do further research into. In fact, it’s often a great motivator to do so. Just don’t pick subjects you know absolutely zero about, people expect some experience or credentials from their speakers (unless your talk is “How I Stumbled Through Putting X into Production” which is also valid as an intro tutorial).
  • Sad to say but it’s still often about who you know. Find out who the influential speakers or groups in your area are and go out of your way to meet them. 90% of them will already want to help.
  • It’s all about getting that first talk. Once you have that done, you can use it to get the second and the third and…

Writing

  • Start writing with lots of time. Literally, at least a month out.
  • The #1 tip: If you have bullet lists, break each bullet point up into an individual slide.
  • If you do have lots of text on the same slide, use the appear animation to stagger the lines. Otherwise, people will read ahead and not listen to you (or worse, become bored).
  • There is no right number of slides. I’ve seen great speakers use anywhere from 20 slides to 280 slides for 45 minute slots.
  • Don’t start writing slides at the beginning of the talk, skip to the cool technical part you want to talk about. Get that section right and then build the rest of the talk around that.
  • When writing, I often sketch out 30-60 seconds of talking, then backtrack and create the slides for that. Then I do that part again with the slides, adjust or scrap, then write the next 30-60 seconds of talking. Repeat until done.
  • It’s good to have an About Me intro but keep it under 45 seconds.
  • Anticipate the questions your audience will have at any given moment in a talk and then address them immediately. If you don’t, they’ll stop listening to what you’re saying until its question time while they mule this over or wait for you to address it.
  • Don’t ever be afraid to rewrite but don’t make major rewrites in the days leading up to the conference, you will forget and goof them.
  • Your talk doesn’t need to have a story, but build it like one. It should have a lead-in, build up, a climax and a resolution. Emotion has a place, even in technical talks.
  • If you’re having trouble finding a voice, pick speakers you like and imitate them until you find one that feels comfortable. That’ll put you in the right area, then refine it until you find yours. This doesn’t have to be a technical speaker: in fact, I’d recommend stand-up comedians. That’s not to say it has to be funny, but these are folks with the stagecraft to keep an audience enraptured for hours with almost nothing but talking. You can learn a lot from them.
  • Gimmicks can lend spice to a talk but don’t over use them.
  • The only good animation is the “appear” animation. Don’t use animated slide transitions and don’t let meme GIFs loop indefinitely.

Talk Formats

  • Don’t do live demos. These are high risk, high reward propositions. If it goes smoothly and it’s genuinely impressive, you might look amazing. That said, almost every live demo will crash and burn horribly. Including yours.
  • If you do go this route, remember: it will also likely take more than network communication to genuinely impress the audience.
  • Likewise, live coding is a universally bad idea. Even if it goes perfectly (and it won’t), the speed at which you can deliver is severely reduced. Even amazing developers are boring after 30 minutes of typing at a podium.
  • Instead, consider making a screen recording and embedding it in your presentation. This can fail too but the odds are much lower. You can also speed this up, pause it, rewind it, etc and it leaves you more free to talk and manage your time without fear.
  • Never count on an internet connection. No, not even with speaker-only wifi. No, not even tethering on your phone. Never. Count. On. Internet.

The Weeks Before Your Talk

  • Practice. Practice Practice practice.
  • Always back up your presentation twice: a USB stick that you carry with you and and online (email, Google Drive, Dropbox). Don’t forget the additional dependencies like fonts, movies, etc.
  • Always ask about the projector connection beforehand. Be prepared. When in doubt, prepare for VGA. The only place this might not be true is development offices: many are populated exclusively by Mac users and may not have a VGA adapter on hand.
  • If you’re a Mac user, bring your own connectors. Many conferences have them, but many don’t or have a limited supply.
  • Don’t get drunk the night before your talk. Seriously, be a professional. Conference culture features a lot of drinking but attendees paid good money to see you speak so don’t show up with a hangover. Even if you’re in the afternoon slot, save the booze for the post-talk celebration.
  • Even a cheap remote is worth its weight in gold. Seriously, don’t get on stage without a remote, it’s incredibly freeing.
  • When practicing, don’t just stare at your monitor since this will become a bad habit when you present. I once suggested giving your talk to a stuffed animal since you can make eye contact with it; silly as it sounds, an elePHPant makes a great reviewer.
  • Controlling your body language is important. Practice your talk standing up and work hard on creating a firm posture: it looks good to the audience but more importantly, it keeps you calm and projects your voice. Fidgeting will make you nervous, unsteady and distract the audience.
  • You’re going to be standing for almost an hour and talking, which can be a surprisingly physical strain. Practice so you’re ready for this. A lot of the exhaustion can be bad breathing techniques, which you can work on.
  • When practicing, you’ll often go over time a few minutes. That’s usually okay. When giving your talk, you’ll probably speed up a bit or not backtrack as much in practice, so it’s going to go quicker. Eventually, you’ll find out what that magic number is and be able to plan accordingly.
  • Until then, prep carefully, don’t plan too much material and think about your pacing and what you can cut or extend if necessary. Always build in an escape hatch or two.
  • Practice more!

The Day of Your Talk

  • Sleep well. Have a decent breakfast, nothing too crazy.
  • Practice your entire talk the morning of the conference if time allows.
  • Resist the temptation to tweak anything else with your slides, it’ll just disturb your practice. It’s time, you have to play it as it lies.
  • Dress accordingly: Comfortable shoes are a must. Think about how you’ll look in the room: If it’s dim or darkened, don’t wear all black since you’ll look like a floating head. If you’re standing in front of a colored backdrop, don’t wear something that blends in (like a red shirt in front of red stage curtains).
  • Show up early. If your conference has a room monitor or an assigned volunteer for you, check in with them, learn the their name. If the crap hits the fan, these folks can save your bacon.
  • Always attend sound check if you can. Find these problems early.
  • See if you can get a peek at the room or stage first. Pace it, see how it feels. Set your laptop up somewhere and see if you can see your slides comfortably.
  • It might be worth skipping the talk in the slot ahead of yours and find a quiet corner to review your slides right before. This helped me a lot when I was starting out.
  • Not to sound like your parents on a car trip, but use the bathroom first. Yes, even if you don’t think you have to.
  • If this is your first talk, it almost seems tradition that you’re going to come down with a cold right before hand. Take something with minimal side effects (acetaminophen or paracetamol) or suck a cough drop. If you’re congested, nose spray is the best thing but it doesn’t kick in until 5-10 minutes later so don’t use it just before going on stage. Whatever you’ve got to do, do it.
  • Hand-mics take training to use well, so skip them in favor of anything else if possible. Face mics or lapel mics are the best but even a fixed podium mic can be better.

The Moments Beforehand

  • Once the previous speaker is totally done, wait for them to clear the podium and then setup ASAP. If the speaker is taking a little while and is answering private questions, give them a minute before heading to the podium. They’ll usually see you standing there with your bag and take the hint, but if they don’t, it’s okay to ask politely if you can go ahead and setup.
  • Soundcheck everything real quick and check the space. Check you can see your laptop clearly from where you want to stand. Check your remote batteries.
  • Silence your phone and dump it in your bag. Otherwise, you’re going to get a tweet notifications during the talk and folks will start tweeting at you, just to troll you.
  • If you’re feeling good, maybe do some pre-show audience particpation. Talk to folks in the first row, goof off a bit. I used to play nyan.cat on the big screen to loosen everyone up.
  • Breathe and relax. These are often the scarest moments but it’s going to be okay.

Giving Your Talk

  • The number one thing new speakers goof is looking at the big screen. Look at your laptop. Look at the stage monitor. Look at the audience. Never, ever look at the big screen. Yes, I know it’s big and shiny. Don’t look at it. You’ll twist and turn, ignore your audience, etc. It’s bad.
  • Likewise, don’t use your laser pointer. If there’s something on a slide you want to highlight, add that to your slides as an arrow or highlight or fade out surrounding text. Laser pointers tremble, distract and can even make the audience vaguely nauseous.
  • Don’t go too fast. You’re likely going to freak out a bit the first time and go too fast. I’m infamous for doing this from the early days of my career. Time dilates on stage, what feels like an eternity on stage will often prove to only be a bare second on the video playback. Speak clearly, relax.
  • Most room monitors will give you a signal at important time intervals: usually 15, 10, 5 and 1 minutes to go. Give them a little nod or thumbs up to confirm you saw. Don’t freak out at the signal. Trust in your training, hold your ground and hold your pace.
  • In tech, it’s common to see folks poking at their phones or laptops while you’re speaking. It’s not disrepect or boredom, we’re just multitasking geeks. Often those folks poking at their phones are sending out tweets about how awesome you are.
  • Look at the audience when speaking. Consider all parts of the room. Pick a few faces here and there and rotate between them every couple of minutes. Don’t go creepy-stare-face but look for friends or people into it, use them for support.
  • Consider the local culture. At the risk of stereotyping, crowds have different vibes depending on where you go: the British laugh a lot, even when you’re not telling a joke so plan for it. The Dutch are more restrained but don’t do audience participation. Adapt accordingly.

Handling Questions

  • Always repeat the question to ensure you understand it, and for both the recording and others in the room. This is a hard one to remember but it reflects well on your polish.
  • Check your room monitor for how much time is allowed for questions (if any). If there’s no room monitor, check the time discreetly.
  • The knowledge level in the room can vary enormously. Even beginner questions deserve your respect. Never use your position to denigrate someone.
  • There’s a chance you’re going to get “pointed” questions, which are often not questions but argumentative attendees or someone looking to take a whack at you. These often come with elaborate backstories or a particular tone or a “don’t you think…”.
  • Don’t ever take the bait on these, the moment you become angered, you’ve lost control of the situation. Instead, try to answer factually and calmly. Always take the high road. Often, there’s a veiled barb or underlying question, it can be helpful to address that head on. If you can’t resolve the question directly, offer to talk to the attendee afterwards. “Hmm, well, come talk to me afterwards” can get you out of almost any sticky situation.
  • If you get a really advanced or tricky question that you don’t know the answer to, don’t BS it. People can smell it and someone might call you on it. Again, you can get really far with: “Hmm, that’s a good one, I’m not sure. Come talk to me afterwards and we’ll see if we can figure it out.” If someone from the audience calls out an answer, always be supportive and thank them if it sounds legit: “Oh, good one, that might work”.

After Your Talk

  • Say thank you, point folks to your joind.in link again with your final slide.
  • Remember to switch off your mic!
  • People are going to come up to the podium to ask more questions. Say hi, be inviting and polite to them.
  • While you’re doing the private questions and riding the endorphin rush, pack up your stuff and clear the podium ASAP. The other speaker will likely be fidgeting and ready to get setup almost immediately. Take the remaining questions off to the side or out in the hall.
  • Double check you’ve got everything (I always forget my remote’s sheath) and leave the mic for the next person or hand it over to the room monitor.
  • Handle all of the private questions before disappearing. If someone is taking up too much time, politely give them a hint or just give a gentle acknowledgement to the next person in line. Try to at least hear everyone fairly quickly, since folks will often head off to the next talk. You can always make an agreement to meet again later with folks who have larger issues. Triage.
  • Have business cards within easy reach.
  • Don’t just leave the conference now that your talk is done. Stick around, meet folks, answer questions. Part of the experience people pay for is getting to hob nob with speakers, network and talk to you in hallways and socials. Remember, that’s what you were flown in for. Be professional. Hiding out to relax for a slot after your talk is okay but blowing the conference immediately after your talk is prima donna BS.

Social Media Followup

  • Post your slides to Slideshare/Speakerdeck/Wherever and tweet them on the event’s hashtag. It’s acceptable to do this via the joind.in page so you often get more feedback.
  • Odds are, you won’t be happy with your performance. That’s okay. It means you still have potential to become a better speaker. Honestly, I’ve had talks I felt were bombs that the audience was still satisfied with. The ultimate metric here is how you feel about things and if you communicated your message.
  • Don’t freak out and start checking your reviews immediately. Give it some time and let a few trickle in. Take them seriously, try to improve whatever folks mention. Don’t post defensive comments.
  • Likewise, reviews tend to be dominated by folks who either loved your talk or hated it. Rarely do you get both camps under one roof, so keep it in mind. Often a bad talk on joind.in simply gets the “crickets” treatment (though as a new speaker you’ll often have smaller rooms and thus fewer reviews). If you had a well attended talk but got noticeably fewer reviews than other talks at the conference… you may have some soul searching to do.
  • Vicious reviews can happen. They’re designed to hurt the most but sometimes they contain an element of truth. Take something constructive away if you can, but ultimately, screw those haters.

Hanging Out in Hallways

  • Once you’ve given your talk, folks will randomly ask you questions all the time. Handle them with respect (unless you’re, you know, using the bathroom or something).
  • Many conferences have separate badges for speakers. These typically draw attention to you and people want to ask what you’re speaking about, etc. This can be great for networking or breaking the ice but you can also just flip the badge around backwards if you’d like to have a normal conversation.

The Social

  • You’ll get more technical questions at the social so be ready. Also, a fair number of people will just want to come up and meet you, shake your hand, etc. Always be willing to interrupt what you’re doing and shake someone’s hand because it’s going to happen.
  • Don’t hang out with just the cool speaker crowd, make an effort to meet random folks. Also, treat everyone with respect and assume they’re smarter than you; you never know when someone you casually met is actually hugely famous (this has happened to be a few times).
  • If someone is monopolizing your time or making you feel uncomfortable, you can always excuse yourself to get another drink or take a bathroom break. (I’ve only had to do this twice in practice so if I’ve ever done this at a conference, please don’t think I was avoiding you).
  • Folks will often offer to treat you to free drinks, so be gracious but judicious in accepting. Being a speaker doesn’t entitle you to anything.
  • Take the time to find and thank the organizers. They work hard and do appreciate this.
  • Okay, now you can get a little drunk.

The Less Than Glamorous Tips

  • Your nose might start running during the talk. If so, take the time to turn away from the mic and wipe it. Nothing is worse than a speaker with the sniffles, especially with a face mic.
  • Bringing tissues, cough drops and even nose spray is often a very good idea. Always keep an open tissue in your back pocket or on the podium. Cough drops are also a surprisingly good ice breaker with other speakers.
  • Stage lights can be blinding. They’ll also make your eyes water and your nose run even more. Try to get used to them during sound check since this is the only way you can practice, short of staring into the heat of a thousand suns. Before the talk, when people are filing in, take note of where they start to sit. This way, if you really do become blinded, you can still pretend to make eye contact with the audience.
  • Con Flu is a real thing and you’re going to be shaking a lot of hands. Washing yours regularly might reduce your chances of getting sick afterwards.

Having spent the previous weekend at LaraconEU, I wanted to jot my thoughts down about the conference, particularly some of the upcoming features unveiled by Taylor Otwell (the framework’s BDFL). To clarify, I’ve never used Laravel, have no plans to do so right now and all of these features are still in active development. I just want to talk about technical and community impressions so take everything you read with a grain of salt.

New directory structure

The next big Laravel release is going to ship with less of a Rails-inspired structure (think: app/models, app/controllers, or ZF1) and will instead move to a PSR-4 structure. This looks great for 2 reasons: first, it brings the framework more in line with existing community standards (and tooling). Second, I believe this change will encourage devs to design their objects more freely, rather than try to fit everything into the pre-labeled types of objects.

Taylor is also shipping a plugin that will support the old directory structure seamlessly, so you can go ahead and upgrade to the other stuff without letting this change hold you back.

Autowiring

One of the most controversial parts of Laravel are the Facades, essentially static shortcuts to objects in the DI layer. Stealing an example from the docs, you might have a controller like this:

class PageController extends BaseController {
    public function showStuff()
    {
        return View::make('some.template', []);
    }
}

In this case, the View object is the Facade. Being static makes it convenient but harder to test and isolate. While there’s some interesting stuff going on behind the scenes to make it somewhat testable, the new version of Laravel renders the point moot by adding autowiring IoC to more objects, like controllers. This lets us rewrite the above example to:

class PageController extends BaseController {
    public function showStuff(View $view)
    {
        return $view->make('some.template', []);
    }
}

This seems like a small change but the effect is profound. Our dependencies are clearer and we can mock them very easily. This new feature preserves the ease of use, makes room for better OO, and does it without breaking BC. Nice.

I’m not a huge fan of autowiring IoC myself but considering the tradeoffs, I think this is a great change. In fact, I’d go far as to say this is the killer feature for the next version and would highly recommend Laravel devs upgrade just to get access to this (when it’s deemed stable, of course).

Custom Requests

The most interesting feature was the new customs Request classes. Essentially, this let you create typed HTTP requests with custom validation and authorization rules that run before allowing access to the controller.

    class UserController extends BaseController {
        public function createUser(CreateUserRequest $request)
        {
            // do stuff
        }
    }

In the example above, if the HTTP request is a POST, the $request is already prefilled and validated before ever reaching the controller, cleaning up the code a bit. The custom Request classes can be generated with an artisan command to save some boilerplate setup.

Once you see it in action, it’s pretty clear this is an integrated Command Bus, which is pretty fascinating. If you know me, I’m bonkers about command bus service layers and this is the first time I’ve seen a framework take an opinionated stance in that direction so I consider this a plus.

At the same time, there were unresolved questions about this feature to me. Can I easily reuse this in CLI scripts to trigger the same actions? How extensive is the coupling to Laravel’s auth and validation libraries? Isn’t there a lot of state flying around with request method dependent behavior? Shawn McCool had some interesting ideas about this so I’m reserving judgement until I see the final feature.

Regardless, I can’t help but feel it’s a really cool to see a framework take a step like this, even if I have quibbles about implementation. Again, this seems like a measured tradeoff between ease-of-use and best practices.

Contracts

One of the coolest things at the entire conference was the upcoming Illuminate\Contracts repo, which is a repository of only key Laravel interfaces. This opens the door to a lot of standalone implementations and hopefully better architecture overall. This is something I’m 100% behind and hope to see more frameworks do in the future.

One of the new interfaces demoed was a Filesystem, with the first adapter backed by the Flysystem library. I think this is also fantastic for several reasons: OO filesystem access makes testing and decoration easier, Flysystem is a great library that deserves more attention and finally, this might help Frank de Jonge eventually become more famous than Scott Wilcox.

Socialize

This is a new social login library that’s coming with the next version. The version demoed used a static facade which I thought was unfortunate, but the functionality looked great. The application had a github backed login with literally less than 10 lines of code.

Wrapup

Looking at the decisions Laravel is making, I feel it’s moving in a good direction, while preserving a preference for leverage over abstraction. And you know what? That’s okay.

Generally, the audience felt open and willing to discuss challenging subjects. Topics like TDD and service layers were regularly discussed in the halls and I wish I’d had more time to mingle and meet folks. The level was mixed but folks were hungry to learn more. It wasn’t perfect, there were some awkward moments and not everyone was on board with everything. Nonetheless, there was definitely a feeling of going forward.

I’d like to give a shout out to some of the newer speakers like Kayla Daniels for an amazing first talk fighting the good fight, Ben Corlett who should speak at more conferences, Erika Heidi the most improved speaker every time I see her, the fine speaker and gentleman Kirk Bushell and Matt Stauffer whose delivery will likely give me a run for my money soon.

I want to compliment the organizers for putting on a great conference. They’re friends of mine, so I have an obvious bias, but I thought everything from the food to the schedule to the venue was great.

There are some other possible reasons for this positive impression, it’s no secret my step up from dark horse speaker to closing keynote garnered me a lot of love. Still, I’d like to believe it’s because the Laravel community is starting to shed its reputation as a framework for beginners and making moves to stand as a valued member of the wider community; something should all welcome.

Note: Everything in this blog post is purely theoretical, treat it as a thought experiment. I haven’t tried this yet.

I’ve been thinking about use cases for Event Sourcing (ES). It’s most often associated with backend applications where you need strong audit logs but I’m starting to wonder if it might be a good fit for some Javascript single-page applications (SPA) as well. There are folks doing ES in node but I haven’t seen anyone try this in the browser yet, so I’ll try to outline a few reasons it might be worthwhile.

This article assumes you’re already familiar with ES. Still, just to be clear, I’m suggesting a move away from JS persistence like this:

// JS
var product = new Product({
'name': 'Foo',
'price': 90
});
product.set('price', 60);
product.add('tag', 'awesome');
product.save();
// HTTP
POST /product
Host: example.com
Content-Type: application/json

{
    'name': 'Foo',
    'price': 60,
    'tags': [ 'awesome' ]
}

to something more like:

// JS
var product = Product.import('Foo', 90);
product.discountPrice(60);
product.tagAs('awesome');

eventStream.append(product.id(), product.getPendingEvents());
eventStream.flush();
// HTTP
POST /events
Host: example.com
Content-Type: application/json

[
    { event: 'ProductImported', name: 'Foo', price: 90, id: 'some-generated-uuid' },
    { event: 'ProductDiscounted', price: 60, id: 'some-generated-uuid' },
    { event: 'TagAdded', 'tag': 'awesome', id: 'some-generated-uuid' },
]

In the first example, we’re using a pretty standard getter/setter, ActiveRecord model. In the latter, events are generated inside the entities, loaded into an event stream and then flushed to the server in one go.

Okay, so that’s the example. Why do this?

To start, when you build an MVC-ish JS app, you often end up duplicating some code on both the server and client, particularly in the model layer.

We’ve all done the dance: You need a Product model in the JS code but to save it in the database, you also need a Product model in your PHP/Ruby/Java/etc. Then when you need to add a new field, you have to update the Javascript, the PHP, the database, etc. The smell of lasagna permeates the room.

On the other hand, if we used ES, the server wouldn’t receive full blown entities. It would only receive serialized events. If the SPA is the only interested party, the server can just pass them to the persistence layer and the entire process stops there. The JS model would authoritative and the server would be much simpler since most event stores are just serializing the events.

That does bring us to a downside: we won’t need the entities but we will need Event classes and there’s going to be a lot more of those then there were entities.

That said, the events are dead simple and actually useful. This is the code you want to write. You might even be able to reduce some of this in clever implementation, especially on the JavaScript side where anonymous objects would work fine for events.

That said, any extra work is offset by doing away with a big bunch of useless code: the REST API. Don’t get me wrong, I love REST. I love hypermedia. Many of the issues this article describes would be best solved with a really well designed RMM Level 3 API. Unfortunately, most JS libraries encourage CRUD style APIs which can be a poor fit and a huge maintenance burden. If you don’t need or want to design a good API for multiple consumers, then I’d argue don’t even try: a single RPC endpoint is easier to refactor than a pile of near identical controllers and anemic models.

There are several other benefits to the server:

  • Security inspections become much simpler. If you’re dealing with a CRUD API, you need to derive and approve user changes from the data structure. With domain events, the user behavior is explicit, so security checks could be as simple as matching the Event class name to an allowed list per role (or voter or whatever you prefer).
  • The fine-grained behavior also makes triggering other server-only side effects a cinch. It’s already an event!
  • Debug logs are a classic ES benefit and doubly so when chasing errors through a complex GUI.
  • You can have one major transaction for several operations. If you were writing to several API resources, it would be nigh impossible to rollback all changes.
  • Good Domain Events are probably reusable.

I think there’s benefits for the JS as well:

  • ES often brings better surrounding architecture as well, like command dispatching and strong domain models. This can only be good for your JS, which is frequently neglected when designing.
  • Many JS UIs are already evented, listening for changes on individual fields in the model. Unfortunately, listening for changes on a single field might not be high-level enough to express what the update should be, turning the UI management code into a mess. Instead, we could publish the domain events not just to the server but to our own UI, leading to more concise updates.
  • Events open the door to some cool JS features which might normally be hard to implement:
    • Saving everything in one request, both for performance and to avoid sequence issues.
    • Saving events in local storage in case the user loses connection.
    • Maybe even an undo or rewind feature. Event Streams should be immutable but you could potentially do this with only your unsaved actions, provided your models support forward and reverse mutators.
    • Replicating changes to other users like in a game or collaborative app.

This might sound great but as they say, “no plan survives contact with the enemy.” For example, there’s still some duplication between the client and server. The JS will certainly be more lines of code than a CRUD/ActiveRecord style. The ES rehydration process (reapplying the entire event stream to the individual models) may take more CPU on load. And how would you resolve two event streams that differ significantly, say from two users?

To counter these points though: the duplicated Event code is straightforward and easier to manage than multiple CRUD controllers. It’s more lines of code but it’s simpler code. ES rehydration is often offset by snapshotting, which may work especially well if you need several items at once for loading: you can maintain CQRS ViewModels to grab all of your interface’s data in tight blobs. As for merging differing streams, I’m not sure how this differs greatly from a standard ES scenario so the usual solutions apply, say optimistic locking with a version number.

That said, there’s little defense against the additional complexity argument. To make this worthwhile, you’d definitely need a reasonably large Javascript app. However, as Javascript and user expectations continue to evolve, this might not be as rare as you’d think. I’ve already worked on at least one or two projects in my career where I’d consider this a valid or improved approach.

In the largest JS project I’ve worked on used Commands, rather than Events, dispatched to a single endpoint. This was a marked improvement and had many of the same advantages (transactions, some debug log, batching) but it also came with a lot of duplicated code and made you sometimes wonder which was the authoritative model: JS or PHP? You could put all of the logic server-side but you may get a laggy interface for your trouble.

Still, this is theoretical for me so if you know anyone who’s tried this approach, please let me know. I wouldn’t recommend it for most projects but If I could do some of them over again, there’s a good chance I’d give this a shot.

Many thanks to Warnar Boekkooi and Shawn McCool for proofreading this article.

Ansible has excellent documentation but one thing I was confused about was the best way to store the configuration for multistage projects: say, different passwords for dev, staging, production. This isn’t really covered in the ansible-examples repo because it’s specific to your project and while the documentation has recommendations, it doesn’t spell it out completely (which I need since I’m an idiot).

In the old days, the easiest place to keep the configuration was in your inventory file. Since these store the server IPs you run your playbooks against, they’re inherently stage-specific. However, storing everything in the inventory can be limiting and is officially discouraged.

Instead, the best practices guide suggests a different structure, one that’s based on keeping your config in the group_vars and host_vars directories. At first glance, the linked example confused me because it seemed to be mixing a lot things together in one file: IP addresses, role assignments, location, datacenter, etc and then mixing these together. However, after some trial & error, talking to some smart folks and a lot of googling, I’ve hit on a structure that’s worked well for my last couple of projects so I’d like to write about it here.

So, let’s take the example above and pare it down to something simpler:

We’ll create an inventories directory and place a “production_servers” inventory file in there.

; inventories/production_servers
[web]
4.2.2.1
4.2.2.2

[database]
8.8.8.8

This file does one thing and does it well, it sorts our server IPs into different groups. Now, “Group” is the magic word here. Whenever we run a playbook with this inventory, Ansible isn’t just loading the inventory. It’s also looking at the group names we set (the header sections of the INI) and then trying to match those to a file with the same name in the group_vars directory. This isn’t explicitly configured, it’s just something Ansible does by default.

So, since we mentioned a “web” group and a “database” group, Ansible will try to load the files “group_vars/web” and “group_vars/database”. These are expected to be YAML key/values lists and we can use them to define all Ansible variables that you likely have sprinkled throughout your roles. For example, the database vars file might look like this:

# group_vars/database
---
db_port: 3306
db_user: app_user
db_password: SuperSecureSecretPassword1
# group_vars/web
---
domain_name: myapp.com
csrf_secret: foobarbaz

Here we’ve defined a few variables you’d use in a role like {{ db_password }} or {{ domain_name }}.

So far, so good. By now, our ansible directory probably looks something like the example below. Keep in mind the group_var file names are based entirely on the header names inside the inventory file, NOT the naming of the inventory file themselves.

    .
    ├── group_vars
    │   ├── database
    │   └── web
    │
    ├── inventories
    │   └── production_servers
    │
    ├── roles
    │   └── ...
    │
    └── my_playbook.yml

Now comes the multistage part. We don’t want to use the same db_password for dev, staging and production, that’d be terrible security. And we probably want to change the domain name. And the SSL certificates. And all sorts of other things, which we’d prefer to maintain in just one place. How can we group the configuration together per stage?

Remember, Ansible will try to load a group_vars file for any group it encounters in your inventory. All it takes to define a group is adding a section for it in the inventory’s INI file. So, why don’t we create a “production” group?

; inventories/production_servers
[web]
4.2.2.1
4.2.2.2

[database]
8.8.8.8

[production]
4.2.2.1
4.2.2.2
8.8.8.8

We’ve now created a production group and assigned all the production servers to live underneath it so they all get the exact same configuration. I haven’t tested it completely but this is really important if your configuration overlaps between roles, such as using the db_password on the web servers.

However, duplicating all of the IP addresses is a real pain and it would super easy to add another web server and forget to update the list at the bottom of the file. Luckily, Ansible has an inheritance syntax to make this easier.

; inventories/production_servers
[web]
4.2.2.1
4.2.2.2

[database]
8.8.8.8

[production:children]
web
database

This example does the exact same thing as the previous version: it creates a group called “production” but now it’s defined as a group of groups. Any IP address added to the “web” or “database” groups is automatically part of the “production” group (at least, when running a playbook with this inventory).

That means we can now create a group_vars/production file where we can group the parts that are specific to this stage:

# group_vars/production
---
domain_name: myapp.com
db_password: SuperSecureSecretPassword1
csrf_secret: foobarbaz

These are the things we’re interested in changing per stage. Other stuff that’s the same 99% of the time like port numbers or standard users, we can leave in group_vars/database.

Now, if we wanted to add a staging setup, we only need to add two files: a new inventory…

; inventories/staging_servers
[web]
8.8.4.4

[database]
4.2.2.3

[staging:children]
web
database

and a group_var/staging config.

# group_vars/staging
---
domain_name: staging.myapp.com
db_password: LessSecretButStillSecurePassword
csrf_secret: St4gingCSRFToken

Notice that the basic format is the same, and we can use this to add any number of stages we like:

    .
    ├── group_vars
    │   ├── all
    │   ├── database
    │   ├── dev
    │   ├── production
    │   ├── staging
    │   └── web
    │
    ├── inventories
    │   ├── dev_servers
    │   ├── production_servers
    │   └── staging_servers
    │
    ├── roles
    │   └── ...
    │
    └── my_playbook.yml

In the above example, we’ve now added a dev stage which probably lists our Vagrant IP as both the web server and db server. You might also notice a group_vars/all file. This is a special file that Ansible loads in every time, no matter what groups you use, making it an excellent place to stash your default config.

So, using this setup we have a working and reasonably well centralized multistage setup in Ansible. We’ve also got the config split out nicely so we can use ansible-vault to encrypt our staging and production settings. This works really well and I’ve used it successfully in a couple projects now.

However, there are a couple gotchas to notice. The big one is inheritance order. If you define a config value in multiple groups (say, “db_port” in both “database” and “all”), then Ansible follows particular rules to determine which one wins. For this setup, the priority from highest to lowest is:

  • type (web, database)
  • stage (dev, staging)
  • the “all” file

This is kind of bad, because we probably want the stage files to take precedence but the type files are overriding. It turns out, this is because we used the “:children” style to define the stage in our inventory. This marks the “web” and “database” servers as children of the “production” group and as the Ansible documentation says “Child groups override parent groups”. We could try to work around it by making more specific groups and controlling the hierarchy more tightly:

[production-web]
4.2.2.1
4.2.2.2

[production-database]
8.8.8.8

[production:children]
web
database

[web:children]
production-web

[database:children]
production-database

But this hasn’t worked in testing for me because when the groups are equal, Ansible does precedence alphabetically so “web” is still overriding “production”. Also, while more specific, this is quite a bit more boilerplate for each ansible file.

In practice, I haven’t used the type specific group_vars files much, instead relying on role defaults or the “all” file. The end result has been much simpler and I don’t have to worry as much about where something is defined.

This brings us to the second gotcha: This is reasonably simple on the small scale but it can be more complex. Super nice guy Ramon de la Fuente told me he’s been running this setup (or one very similar) for a while and has found it a bit awkward to manage as it grows. I haven’t tried it on a very large installation yet but I’m inclined to believe him. You should check out his latest Ansible article for more tips.

Still, for a small to mid-size project, this is a straightforward, practical setup. If you do need very fine-grained control and you’re not running several servers per stage, consider looking into the host_vars directory which is the same thing as group_vars but per server instead of per group. And finally, remember, Ansible’s group system is essentially a free-form tagging system: it’s a simple, powerful way to build any setup you want.

Like, you know, Ansible itself.

Update: Erika Heidi wrote a great add-on post to this that talks about integrating this setup with Vagrant and how to configure your remote servers

The setup presented here is essentially that from the (excellent) Ansible Docs and Mailing List, I’m just explaining it a bit more. Many thanks to Ramon de la Fuente and Rafael Dohms for Ansible feedback, as well as Erika Heidi and Rick Kuipers for proofreading this article.