Darren Broemmer joins the Rogues to discuss how Ruby on Rails enables a microservices architecture and when it's appropriate to approach your system's architecture with microservices. Chuck and Dave lend their experience and expertise in pointing out some of the challenges with microservices and the power of Rails in enabling the Majestic Monolith. Tradeoffs are discussed and approaches are considered for when parts of an application may make a good candidate for microservices.LinksTwitter: Darren Broemmer ( @DarrenBroemmer )GitHub: Darren Broemmer ( dbroemme )PicksCharles- ClickUp | One app to replace them allCharles- Dev Influencers | Devchat.tvDarren- Paas Platform as a Service | Pass Solution - EngineYardDarren- AppLandDave- Pactool Gecko GaugeDave- drifting COBOLBecome a supporter of this podcast: https://www.spreaker.com/podcast/ruby-rogues--6102073/support.
Hey, everybody, and welcome to another episode of the Ruby Rogues podcast. This week on our panel, we have Dave Kimura. Hey, everyone. I'm Charles Maxwood from devchat.tv. Dave, it's nice to do a podcast with you again. It's been a while, hasn't it? I know. I keep winding up, showing up when you can't make it, and then you show up when I can't make it. Yeah.
Of course, now we both show up, and Luke and John can't make it, so... One of these days. We also have a special guest, and that's Darren Bromer. Did I say that right, Darren?
Yeah, Darren Bramer, yep. Bramer, ah. And O-E, it's a German, German A sound. Ah, nice.
So do you want to introduce yourself, let people know who you are, why you're important and famous and all that cool stuff?
absolutely yeah well first of all thanks a lot for having me on here it's great to talk with you guys so i've been engineer engineer my whole life i will admit that i discovered ruby a little bit later in my career i was a java guy for quite a while and going all the way back to 2002 i'm going to date myself here i wrote a book on java j2ee actually so there you go that there's a dated uh bit of technology a little bit
And so I've done all types of engineering-managed teams. I decided I wanted to go back, get hands-on keyboard after doing that. Went to Amazon Web Services. Had a great time working there. Learned a whole lot. Had a lot of fun. Met a lot of great people. And then wanted to get more into kind of combine the two things I really, really enjoy. So the technology, obviously, but also communications.
And so now I kind of went and switched gears. I'm now the developer evangelist for... Engine Yard and we have platform as a service tools, but I get to do my two favorite things, which are play with technology and share that with people, write about it and talk about it.
Awesome. And yeah, we ran across this article from you talking about architecture and microservices and stuff, which is funny because I think on JavaScript Jabber, we did an episode on micro front ends about three weeks ago. We recorded it anyway. We're a little more ahead on that, so it's probably going to come out in a few weeks.
But it's just interesting because people are talking about this and how to break up application logic and stuff like that. And of course, in Rails, we all talk about the beautiful monolith and you know, how that all kind of comes together to put it all in one app. And so yeah, I'm kind of interested because I don't know that I necessarily got the breakdown on where you come down on this.
And I remember early in my career, like SOA, service oriented architecture was a big thing. And I think I gave a whole bunch of talks and gave a whole bunch of bad advice, because it was the cool thing to do. And I was really in love with the idea. But you know, been built a few apps and took it way too far. And it was like, you know, a lot of this stuff really does belong in its own app.
And then some of this stuff, it started, okay, some of this stuff belongs in workers and some of this stuff actually, you know, may belong in its own service, you know, microservice. And so, you know, I kind of have gone back and forth as to how much you want to peel off into different parts and,
And so I'm kind of curious where you come down as far as, okay, what do I break off into microservices? What part do I keep in the monolith? What part do I, you know, and how do I break that up? And then I also saw some stuff about containerization. So we can, I guess, dive into that next. But yeah, how do microservices kind of fit into Ruby these days?
Yeah, so I think when you're looking at decomposing your application and doing design, you know, and really there's only one reason that we really do software design, right? We do it because we're probably going to need to change our application tomorrow, whether that be to fix some bugs or to add some new features that people want.
We can't, you know, add patterns and layers of indirection everywhere. So we need to make choices. I say that because every time you add a layer of indirection, it's not free. There's a cost to it, right? We can't optimize to be able to change every aspect of the application. You know, for example, I've been on a number of projects over my career.
You know, the team would be, well, we need to abstract this and that so that if we want to swap out the database, Later on, we can. This is maybe a little less relevant now, but I think the example still holds. And so there was effort spent into that. Now, how many of those projects ever actually swapped out databases?
I can think of maybe one that went from a relational database to a NoSQL, and they had to make broader changes anyway. So you need to think about where can I... decompose my logic into reusable bits. And when you think about the basic Rails architecture model view controller, generally speaking, you try to push that logic down in that, if you think about it as a layer cake, down as far as you can.
validations you'll always need to do before you persist to the database. Yeah, put it in the model class. But it becomes very tough when you think about this. There's lots of best practices and things about where to put quote unquote business logic. And in my experience, that often ends up coming back to the service level or in Rails, the equivalent of a Rails action, a controller method.
So if I'm a... You want your code to mirror the real world as closely as possible. And I was... You mentioned earlier, I've probably given bad advice in my career in the past too. I used to be a huge enthusiast of object-oriented. And while I think it's still valuable and has its place, I think in terms of decomposition, if you want to mirror the real world, if I'm a customer, I don't think...
of objects and entities. So let's say I'm gonna go online to pay my credit card bill. I don't think about that in terms of, well, there's an account object and a vendor and a payment behavior. I think about that of, I'm gonna go pay my bill. It's an action I take, something I do.
And so you can try to push logic further down the stack, but usually it ends up kind of bubbling back up to this service layer because those are encapsulated units of work. Now, paying your bill. Now, I personally wouldn't do this, but let's say I was late. I'm paying my bill, so I'm going to incur a fee.
So that's probably another service to calculate what the late fee is based on when I submitted all of that. So you can see that kind of breakdown. And so reusing those services and actually, you know, this almost gets back to like functional programming. It's funny how things kind of come full circle every year. every so often.
But to me, the service level is the easiest way to decompose and be close to how you mirror the real world. And if you can do that, if you can model that closer, you're going to be better off in the long run when you need to make changes. So now segue that into microservice, because microservice often has the connotation of being a separate physical deployment.
So there's different steps you can take to migrate this, right? So you mentioned the beautiful monolith. I might have tons of code all sitting there. It's in one deployable unit. You know, Rome's not built in a day. I can't do all of this at once. So, you know, one of the articles I wrote that you referenced was really just, well, how do I take that first step?
How do I go from the beautiful monolith to whatever my target architecture is, whatever your favorite decomposition model is? So the beautiful thing, one really nice thing about Rails is I think it helps you out here. So even in my existing code base, a controller action, let's say you're using Rack as your middleware, that controller action is actually a Rack, its own Rack application.
So in the Rackup file, rather than just doing Rails application new, you can actually just point it directly to that controller action. So now you can deploy that as a deployable unit. It's going to use the same code base, but from a logical standpoint, I've separated that out from the rest of the system. I can begin to reason about it more, think about What changes when? How do I reuse things?
And then just to tease the topic a little bit, just to throw the container bit out there. So it's an easier migration then to make it a separate deployable unit because that same image, that same code base, I'm just going to have a different rackup file that I use for each of those. I can deploy those separately. I can scale them independently. I can observe them, see...
you know how they behave if one if the cpu goes off the rails on one of them it's going to be easier to identify where the problem was so you don't you don't get those kind of advantages until you actually make them true microservices and you get that observability but there's a lot of benefits when you start to go down that road and rails i think helps rails gives you tools to help do that incrementally so that
kind of an overview of where i'm at there i don't i don't think there's one there's certainly not a one-size-fits-all but to the extent that you can go with microservices to break that out from a logical design perspective and then the the actual deployment get the observability scalability independence i think there's a lot a lot of benefit there
And so just because I can, I want to push back just a little bit and just to get some more clarification. So when we deploy a now isolated bit of code as a microservice,
infrastructure speaking what is that going to look like as far as the database level is concerned are we going to spin up an additional database so now we have a whole new database server with a new database on there or would we just create a new database within a server and
So if we're running Postgres, we have one instance of Postgres or a cluster, and then we have a new database for this microservice, and that microservice only communicates to the one database, or do they all share the same global database?
Yeah, that's a great question. And you're poking at why you want to obviously think through these things carefully. But yeah, no, it's a great question. So what does your data architecture look like? If you're starting out with the beautiful monolith, you do likely have that single transactional database.
So to the extent that you can segregate out by which objects, which models or tables are being used by sets of services, You're better off segregating those and making those their own deployable units. You're still going to have some potential level of contention because you've got different apps talking to the same database. And so one could certainly impact the other.
You can still have a noisy neighbor situation there. But as you migrate over time, if you can decompose your larger architecture into those discrete topic areas where you can have different databases, then you get a cleaner isolation. And that typically takes folks a lot longer to do. And you can also end up in the spot where I need data from both places.
And you can end up getting into performance issues because you get... pretty chatty between these services. So it's not a panacea for sure, but I think to the extent that teams can start thinking in that direction and trying to find those, what are the good isolation boundaries to use? And again, it's not a black and white topic, but there's no crystal clear answer there.
But I think there's overall, if you look at how do I make changes, right? Because in today's economy, you know, with the pandemic and people being at home, like we were already essentially a digital economy. It's almost entirely that way now. So, you know, we're all forced to innovate so much faster, you know, deploy faster.
We were already deploying continuously, and now we want to do it even more so. If we don't do it fast enough, someone else is going to copy our business model. We're going to lose customers we could have. So there's so much pressure to get features out there faster. And so, again, you can't optimize for everything, but it's thinking about, well, what is going to benefit me now?
to isolate where I may want to be able to innovate faster, move separate from the other aspects of the code. One problem that, and even at Amazon, our teams ran into this, especially some of the bigger services where you really want to get a bug fix out or some feature out.
But if it's all in the same kit and caboodle and you've got an issue that pops up with one of the other changes, you got to roll that whole thing back. Because at the end of the day, you can't have ongoing impact to your customers.
And so that is something that I think really hurts teams, their velocity, when you've got to make sure that these 12 or 20 or however many features are all working perfectly in order to get all of them out the door. So rather than an all or nothing, microservices really... help you there.
So you wouldn't isolate everything, but the areas where you know you're going to have a focus on or you can predict or you already know that are important to your customers, that's where you may want to think about it.
So one other thing that I'm wondering about, because Dave was like, well, how do you deal with the database level? I'm thinking, how do you figure out traffic coming in, right? I mean, do you have subdomains? Do you have like Varnish or something on the front that
you know, figures out this path means this microservice, or do you have them talk to each other through, I've seen like RabbitMQ, which I've also seen be a headache. I mean, how do you work all that out?
Yeah. So there's a number of solutions here. I think one nice way to start is just to And here's where an abstraction does actually benefit you because you can put a facade in front of your service. And so maybe you start out with just actually just calling inline. You're just calling the class directly in your same Ruby process.
But then that positions you so that when you do move it out to a service, you can swap that out and it's less of a problem. In terms of the domains, I personally like having the different subdomains Part of that, I guess, the product that I work with, EngineR, facilitates this pretty nicely where each of your apps within the same application just get different subdomains.
But there's obviously different ways that you can do it. And you don't actually, you know, of course, you don't need to split that out because you could just use different URL paths to accomplish a similar goal. But if you get it into containers and you can segregate, then you get those benefits of the physical deployment also. So to me, I prefer to try to keep it simple.
Certainly, there's a couple different choices there. I mean, I would probably, if you can avoid... Putting messaging layers in between. If you can keep it simple, rest calls, unless you need to do something different, I probably would advocate for that. Keep it as simple as possible, but no simpler. But there's also other tools and frameworks that help you do that.
I haven't worked with it in detail. AWS has Service Mesh, which helps you orchestrate all of these microservices. So there are things out there that will help you manage all of this. And probably those are worth it if you really get into large numbers.
If your enterprise is truly bought in and you're going across many different departments and many different organizations, that's probably when you look at something like that.
Yeah, so kind of where I'm going with the whole database side of things, because I agree, if you do have a microservices environment, then you should have a separate database for each microservice. But the issue kind of comes into play is when you start off with just a few microservices, it's fine. It's easy to manage.
But then when you scale up to 100 to 1,000 to 10,000, it becomes less manageable. And you're... infrastructure cost also is scaling up fairly proportionally.
You go past five and I'm getting a headache.
So the issue that I've seen is when a microservice stops becoming a microservice and it becomes a monolith service. to where you have now these 20 different or 40 different microservices that just have grown and grown and grown.
And now you have 40 separate full-fledged Ruby on Rails applications that are so highly coupled and dependent on each other that would it have been better to just have built it into one beautiful, majestic monolith?
Yeah, I had a similar reaction that Chuck had. If we get into the thousands, I'm completely with you. We've probably gone off the rails at that point.
I think that's where Netflix is at. I don't know how many they have, but I've seen their data map of their microservices and communications. It looks like a whole globe of just jumbled spaghetti mess.
I believe that's probably correct. I actually got to work with them a little bit when I was at AWS. They also are a bit of a snowflake because, I mean, there are very few companies or organizations that have the amount of resources that they have. Companies like Netflix, like Amazon, You know, there aren't very many folks that can put that many resources on it.
And they have a vast amount of capability as well. I think for small and medium-sized business, you're looking at a different category and a different type of architecture. And it would probably not be good if you got into those numbers. I will say on the infrastructure cost point that you brought up, I think that would be true on... if you're on instances or virtual machines.
However, containers are very efficient at this. You can put a lot more container processes on the underlying hardware, and you also get a lot of those other benefits that I mentioned. So I don't know that the infrastructure cost would be quite as bad as you think it is because the container processes are pretty lightweight. They can start up in milliseconds as opposed to...
You know, like an EC2 instance probably takes like between 30 and 60 seconds to start up. Whereas a container, let's say, let's round it off to a second. So you can scale those up and down really quickly and you can pack a lot more onto a physical cluster as well. So I don't know if that would be as much of an issue, but on the complexity front, I agree.
There's some point where it becomes unmanageable. Yeah.
The infrastructure scaling pricing that I was referring to is more on the database side. Because on a small tier database, that's really all the application needs. But because you have scaled it up to 50 or 100 microservices, you're not going to be able to connect to that same database instance.
with the lower tier plan because of the number of max connections that's available on those various plans. You would have to either spin up multiple database servers, in which case you incur scaling costs there, or have one really large database server where you have multiple databases within there. And then you still incur a higher cost just for that max number of connections.
Now, AWS may have something different now where you can allow more connections, but each microservice would need at least its one own dedicated connection to the database instance.
Yeah, unless your databases are of pretty decent size, I would probably go the route you mentioned where if you're talking AWS, you have an RDS database and you can put multiple, not instances, multiple schemas on there, right? So at least you can segregate it that way. You know, if...
Many of these microservices, if they have a smaller footprint, there's no real reason to have a different physical instance. You don't need to take that separation to the nth degree. Not to be too salesy, but the company, Engine Yard, also has a ScaleArc product, which is a database proxy, which is also a nice way to... actually get the three-tier architecture independence.
Actually separate out your application tier from your database by connecting to the proxy, and then it can talk to all of these other databases, make them look like different connections, do intelligent caching and security controls for you. Again, if you get into larger number of databases, that might be something that's helpful.
But yeah, packing multiple database schemas on the same RDS cluster is actually pretty good strategy in a lot of cases, unless you have a really high volume or a really large size database.
Yeah, and the whole container idea instead of the virtual machines, I really do like. And I think that especially, even if you stick with a monolith version of your application to do auto scaling, you can more instantaneously respond to the demand coming in, opposed to provisioning a whole new virtual machine. So I'm really with you on there with using Docker containers and stuff like that.
Because I think that's... the proper way to do auto-scaling because you get instant reaction to your users instead of having to wait. Okay, we're at a 50% CPU usage load across all our VMs. We need to hurry up and add more servers, all automatically, of course. But then 15 minutes later, the server's provisioned and now it's ready. Well, that traffic's all said and done now.
Absolutely. So yeah, those two things that we've been talking about, the microservices and the containers, are most certainly independent. So like you were just saying, even with beautiful monolith, containers give you a lot of benefit. They give you this really fast scalability that you just talked about.
And something we haven't even mentioned yet, it's actually pretty nice for development as well. So developing with containers is
really helps cut down on you know how many times how much time in my career have i spent getting my workstation my development environment set up the way that i want it and you know managing those things so using containers for development is really nice for that there's also some really nice tooling to help out there as well so We offer Dev Spaces.
There's also an open source Gitpod where you can, with a single click, bring up the online IDE. It's running based on the container that you define, and you can also do some simple automation. So for example, you can have it on startup, do your bundle install, start your rail server, it opens up a preview window inside of your online IDE, which is based roughly on VS Code.
So you can use those extensions as well. So yeah, so you get benefits from containers, not just in the deployment, but I think in the development as well. And hopefully you never have to hear the phrase works on my machine again. That helps to alleviate some of those issues.
Until you get half the developers using ARM, the other half using x86 platforms.
Yes, there's a whole other paradigm shift that we now have to think about, right? Well, I know a lot of the Ruby gems do work on it, but there's a handful that don't. And I know the company I work with is actually... We're investing, actually looking for Rubyists to help get all of those gems up to speed on ARM because the price improvement... Sorry, the performance...
And price improvement is really significant. So it's a big boost.
Yeah. I couldn't have said it better myself. I have an 8-core Mac Pro, 192 gigs of RAM. Thing is a monster. Then I have a 13-inch MacBook Pro M1 with 16 gigs of RAM, whatever it comes with. I can't tell a difference in performance. On my day-to-day tasks, I really cannot tell. The difference there is a huge price tag difference. It's insane.
So the M1, the whole arm movement that Apple is doing, I think is amazing. And if they can keep it cost effective, then it's going to really make a huge difference in how we approach things.
No doubt. 100% agree. Now that I'm a developer evangelist, I shifted from engineer to, I guess you could say I'm on the marketing side. So still an engineer at heart. But the phrase game changer gets overused so many times. When you go to conferences, you hear, this is a game changer. That's a game changer.
I think the use of ARM, what we're talking about here, I think actually does fall into that category. I think it's a big shift and you're going to see a lot of energy put toward that. And I think it's really going to help things out. I mean, people complain about sometimes Rails being slow. It's like, well, if you run it on a faster computer, that's a really nice way to solve that problem.
Certainly cost effective there. It's a lot cheaper than the person hours that you might spend diving into that potentially.
Yeah, I want to move us back toward microservices here for a minute because I just remember the nightmares I went through moving stuff to microservices back in the day. And I can kind of imagine scenarios that are somewhat obvious, right? I mean, you know, you can move your
authorization right over to microservices and then you just you know maybe do some permissions checks or you know authority checks validate that somebody's actually who they say they are against their identity on the machine or on the other service right and so that's kind of a
an obvious one to me, but I remember we tried to split our app up into services and things were pretty tightly coupled together. It's because the concerns blended from one thing to the next, from one step to the next or stage to the next as things move through the system. And so there really wasn't a clear cut, a clear place to cut.
And so when we picked one, because it's like, oh, well, this is stage one and this is stage two. So we're just going to cut it between stage one and stage two. Well, it turned out that stage one and stage two still have a lot in common. And so, you know, there's not that clear delineation. And so it gave us problems.
And, you know, I'm thinking about some of the apps that I'm working on now, and a lot of them have that same problem. And that's why this monolith idea works really nicely, right, is because all of those concerns that kind of span the entire app are all in there. So how do you start to really think about, okay, you know, this is a good option for microservice.
And this maybe does belong in a monolith.
Yeah, it's a great question. So, you know, I mentioned that earlier, I wrote a book with the phrase best practices and a title. And I think I have a little bit different opinion take on that now. I believe that the use of microservices, what we've been talking about, is a great practice to do if it works for you. And it's probably, you know, it's not a one size fits all.
So it's more of a concept that you can apply to your situation. If it's really hard to to untangle those concerns, maybe you just keep it in that single app. Maybe it's not worth doing, not worth the effort to break it out.
So I basically have a general rule of thumb when it comes to microservices. If this feature, so let's give a real world example. Let's say if I'm in the business of PDFs and whether I'm a government or whomever, and I want to have the ability to take in a PDF and then have it automatically do the form fill out based on the parameters that are coming in.
So this is a very useful feature for one of the applications I'm developing. Within our same organization, this feature is also very useful for five other applications that we're developing. So because this feature can provide a lot of usefulness to these five different applications. And we can come to some kind of compromise or agreement on its API of how it should look.
It should be taking a form post with a list of parameters. It should have an ID of a PDF that is stored on the database or wherever it's stored. Then we can have one code base that serves five applications. So I think that's a good use case of a microservice. It does one thing. It does it really well. And it is highly reusable, not only in my application, but in multiple other applications.
Yeah, that's a great example. And I think that if you've identified that as a need, it's used in more than three places, which is a good general rule for reuse. So you want to package that up and not repeat yourself across that group. So how do you deliver that capability to the other users of it or even reuse it yourself? And so...
You could just point the other teams or the other developers to the repo. You could build a gem, package it that way, which is also a nice way to do it, or the route that you described. You could make it an API or a microservice, and it is. It's well-defined, and it is. That's a perfect use case for a microservice. I will say, Chuck, you also brought up the authorization.
So those kind of non-functional concerns are... prime candidates as well. They're easy to separate out from the rest of your application. That's where you get into the nitty gritty of the business logic or workflow where it becomes a little bit harder to do it.
I will say though, to try to tie some of these threads together, you mentioned earlier, Dave, that Netflix has thousands of these and really AWS does too. So one thing I realized that when I was there was One of the best things that Amazon does is they make each team be essentially like its own startup company so that that team can innovate as fast as they can and deliver value to customers.
And then I also say the worst thing that they do is that very same thing because you have all of these teams not always marching to the same beat and kind of repeating some things or not always going in the same direction. But
All of these different web services are not, it's not really, customers think about it as one infrastructure or platform that they're using, but it's really 150 different services. I think the number is actually higher probably now. And so when you're building one of those, you're using easily 10 or 12 other ones in order to compose your application. I worked on a security service.
I helped build Resource Access Manager. In terms of monitoring and other things, obviously, we didn't build our own monitoring service. We use CloudWatch, for example. Authorization, of course, we used IAM, Identity Access Manager. So it's really... Those are good examples of large sets of services. You can think of them as microservices. Some are more coarse-grained.
But in order to build up these really large, really large platforms that can do amazing things that run a majority of the internet when you think about it. And so there's a lot of capability there. Again, it comes with the caveat like we talked about before. Those type of companies have... armies of engineers who can work on all of these things.
Most of us are not in a position where we have that many other teammates and teams to help us do this. So you kind of have to right-size these design principles for the scenario you're working on. But yeah, there is no one right answer. You always want to apply it to your situation.
I guess the other end of that, right, is how big does it have to be to warrant putting it into a microservice as opposed to putting it into a delayed job sidekick rescue worker or just sticking it in like lib or app services or whatever as just a library that just does a thing, right? And then just gets called out somewhere.
Yeah, I would... So here's where we get into... I would evaluate the deployment or sorry, the operational aspect of it and see what you can get there. So if it's a sidekick job, you're going to have a little less, you'll have to make sure you build in the metrics and the visibility to see how that is behaving.
If it's its own microservice, which you can, let's say it's in a container, I can observe that independently very easily. I can scale it separate from everything else. So if you, let's say you have your web app and a sidekick process. So you're taking orders on the front end and sidekick is doing some fulfillment on the back end. Right.
So if you make a change and let's say that the CPU spikes or you identify a memory leak or some other problem, you know, it's not going to be immediately obvious. Well, was that one of the changes that went into the web app or was it the asynchronous job? And then what's the impact of that? The impact is much different, right?
Because your focus, you should have a relentless focus on your customer. So if it's the web app, they can't take any orders. If it's the sidekick process, it's like, well, that's a little bit better. I can still accept orders and I'm going to hopefully get that business. I might just be a little delayed in getting the shipments out or processing whatever it is.
So having it be its own, if it's valuable like that, right? If I can get benefit from observing it and scaling it separately, then you're in a better spot. If you need to scale up that back-end process, if it's doing more work, then maybe it's nice to have it in a separate deployable unit.
But those are the types of considerations that I would look at as opposed to, or in addition to, I should say, the separation of concerns and how easily, how easy is it for me to make code changes if I need to innovate add capabilities?
Yeah. So I have a little story that I'll try to make tangible to this. So I've had a number of dogs growing up and one of the dogs, you know, was a Border Collie. So the nature of the Border Collie is a herding animal.
And if we had installed an invisible fence around our yard, it really would have confused the dog because that dog is meant to be more free and it would have hurt its nature, essentially. So we got a chain link fence, which was a physical, visible boundary around the yard. And I had another dog who was not a herding dog. They're more of a guard dog.
So that dog wanted to be around me all the time. It was a Rottweiler Doberman mix, which I named her Kitty. But that's a different story. And I could let that dog... out of the yard, you know, into a open backyard and run free. And we never had to worry about her because she always quickly came right back to us because she wanted to be right there next to us.
She wasn't interested in hunting or herding. So the idea of, in translating this back over to what we're talking about with microservices versus monoliths, I think that the monolith is more like that big open backyard without any boundaries.
And if you're not careful, it's not a matter of if, but just a matter of when are you going to have an accident or a mistake on your hands because you have now gotten too much cross-contamination within your application. You weren't careful with the boundaries and And you broke a lot of single responsibility principles.
And now things are too tightly coupled and intertwined in together and you have a mess. Whereas the fenced-in backyard is more like the microservices where you are forced to stay within this confined area. Which means you are forced to... think about and write the single responsibility principles because you don't have access to the outside world beyond your gated fence.
And I think that if we are talking about a single application, that its code base is never reused anywhere else. So I think that we can train ourselves as developers to have more responsibility in how we are writing our code to not introduce a lot of this cross-contamination of logic, which really should be separated out.
And by doing that, like Chuck said, with the lib or app services or interactors, whatever kind of naming you want to call it, but these plain old Ruby objects where you're encapsulating and building these virtual fences around that bit of logic, then you're able to create the idea of the microservices without breaking up the majestic monolith.
That's a great analogy for separation of concerns. I got to remember that one and use that in the future. The dogs in the fenced-in backyard, I like that. Yep. Yeah, I mean, I think that You brought up a really good point. It's like, well, you know, we're all if we're all in the same backyard, you know, how long will it be until we all, you know, cause problems?
We bump into each other trying to get our work done. You know, one person is cutting the grass in the backyard while the others are trying to play volleyball. It just doesn't work very well.
And so, you know, we talked about actually like as it gets bigger, it can get more complicated, but you can look at it the other way that as, you know, it's easy when you're getting started to have it all be in, you know, app and lib. It's actually as you get bigger and bigger where it becomes easier. more of a challenge because changing one thing has ramifications in unintended places.
And that's really one of the big challenges. There's a pretty nice tool that I've been working with or testing out called App Land. And it's open source. You can grab it and it gives you a nice visual map of the connections, the call stacks, and you can see how your components are related. You know, I always like to see, I like to have a visual or mental model in my head of,
their requests coming in and how the route that they take through the controller and what objects they actually use. And this gives you a nice kind of visual representation of that. This was actually something that I thought about when I first started doing Rails and Ruby, which I mentioned like six, seven years ago. And when you do Ruby or sorry, when you, excuse me, when you do Rails new,
It's interesting. You actually get, I think it's about 50 files with 500 lines of code, give or take. And Rails isn't embarrassed about this either because you can do bin Rails stats and it'll tell you exactly how many files and lines of code there are. So that's a lot of code and a lot of files just to do a hello world, right?
If I was going to compare that to Node.js, for example, I think probably one file, maybe what, like five lines, something like that. But there's also the positive aspect of it that it prescribes a lot of things for me. If I want to find out where a controller action is, I know exactly where to look. If I want to find where the images are located, I already know.
So it gives me a great framework to get started. It doesn't, you know, it's not going to stop you from dumping, from making your, your helper's directory become a dumping ground for every, everything known to man and having all kinds of, all kinds of stuff in there. That's not going to prevent that. And that's where the backyard can get kind of messy.
I will say the one having worked on a lot of different projects and different languages and technologies, it's nice. You know, it used to be that on every project you would have the infamous like string helper class. And so it's nice that we don't have to do that in Ruby because the string class is pretty rich and has most of what you need. So we don't have to deal with that.
But, you know, helper directory is always things like that can get messy pretty quickly if you're not careful. My daughter has a Maltese poodle, Peanut. And I'm pretty sure when I take Peanut out for a walk, if I took him off the leash, I'm pretty sure he would go running. I don't think he's the guard dog that would stand by my side.
He'd be down the road checking things out that he's probably like, finally, I get to go run around.
Yeah, that's funny because when I was a kid, we had two dogs. We had a Cocker Spaniel and you know, so she was kind of a little dog and then we had a miniature Chihuahua and she was a littler dog, a much littler dog. She weighed about a pound and a half. Oh, wow. Yeah. She was tiny. And we, the Cocker Spaniel couldn't get out of the backyard.
but she could dig holes deep enough for the Chihuahua to get out of the backyard. And there was nothing we could do to stop it. And so, and that, I guess taking that metaphor to the next level, that's the other thing that you find is if everybody, if you share the backyard, somebody is going to find a way to dig a hole to let people out. That's a great point.
So... Engineers will always find a way. Now we're into Jurassic Park.
Anyway, yeah, it's definitely interesting to think about, but... At the end of the day, I mean, we're just trying to solve problems, right? And it's interesting too, because I keep having the conversation with my coworkers and it's, you know, I shouldn't suggest this because this is work that I don't want to have to do, but this is probably the right solution to this problem.
And, you know, that's what we're in it for, right? We're in it to solve these problems, right? And so sometimes it's going to be microservices is, you know, a terrific way to solve the problem. And sometimes it's going to be, hey, you know, we need to keep all this stuff together so that it kind of all moves and works together in this way.
And sometimes we're going to be in a situation where we just have to make a judgment call. And so I like that that's where this conversation has gone, where it's, hey, look, these are some of the trade-offs that come in this way or that way. And these are some of the considerations you're going to want to make in.
Yeah, that's really well said. These are different tools in the toolbox. And yeah, solving problems is one of the greatest parts about being an engineer and doing what we do. Probably closely followed by seeing our users and customers actually get to take advantage of these creations that we put out into the world. Yep, absolutely.
I mean, let's face it. If you have a really pro team that follows wonderful practices, they're very consistent. And there's no hidden surprises. And if you create a monolith, then it's going to be very maintainable. It's going to be well-tested. And you're not going to have any problems. Take that and compare it to a team that is not very well-versed. They...
are not consistent and they're creating microservices, now you have an application which consists of 100 microservices and each one is its own nightmare. And it can go either way. You can have a team that's great with microservices, they're great with practices, and everything is consistent and isolated in these microservices, and this could be a great application.
But then you have a team that's not as well-versed, and they are just creating an insane monolith that is just unmaintainable. So it's a healthy balance of choosing the right tool for the job and making sure that you have the team and budget to match as well as the infrastructure budget to host, because as we said, there could be differences in which direction you go.
So overall, I think that because I work primarily on Ruby on Rails applications,
microservices doesn't really have a fit in my world because i think the convention over configuration that rails has provided me plus the practices that i have developed over the past 10 12 years has really negated the need for microservices in my world but that could be a different story for someone else where microservices is the answer for them yeah i also just want to uh
I should point out, so the app that I work on primarily these days for my full-time job, it was written to replace another app that was written in another framework in another language. And essentially, it was written very quickly by some very talented engineers, but it was written very quickly and they threw a lot of best practices out the window just to get it out the door.
And so we're dealing with the fallout of that stuff right now, right? Because we're now in the second year, we're coming back around to essentially another iteration of what this thing does. And so we're coming into, okay, we've got to deal with this, and we've got to deal with this, and we've got to deal with that, and we've got to deal with these other things.
And it's, yeah, you know what Dave's saying, it's just not pretty. And it really does, in a lot of cases, come down to your discipline and your willingness to look at these problems and identify where these things are going to come up.
And so whether or not you use one architecture or the other, whether or not you make these decisions one way or the other, what it really comes down to is your discipline in implementing them and approaching these problems in a way that is going to solve the problem in the long term. And Rails does a lot of things that makes it really easy for you to approach this from the majestic monolith.
I kept saying beautiful monolith at the beginning because I couldn't remember the word that DHH used in his blog article. And I have the article up now in front of me. So I'll put a link in the show notes. But, you know, and that's his approach. And so that's the approach that he takes from Rails. But as Darren pointed out, you know,
There are a lot of things in there because it's built on rack that it does exceptionally well that allows you to break it out into services if you need to. And so because of that, it makes it really versatile in your approach. And so, you know, find the approach that works for you.
And then just be disciplined in the way that you approach it so that it does the work that you need it to do to solve the problem that you need to solve. And that's like Darren said, this is the really great part is that we get to go in and we get to figure out the pieces to the puzzle. It's like playing a video game, except at the end of the day, it's not the prescribed path through the level.
It's the, hey, at the end of the day, we got the problem solved and we get to do some really cool stuff along the way to figure it out.
Yeah, those two points were spot on, right? At the end of the day, there's no... Until AI advances to another level, maybe, there's no replacement for the design and the discipline, right? So you do that design upfront and it's like, what's best for my situation? And then the discipline. I think that even after you've agreed on the design, I think there's no substitute for...
those code reviews, right? Like that's where you're really like, okay, are we really doing what we said we were going to do? Are we following our guidelines? You know, that's how you make sure that you accomplish that goal and you don't end up kind of in a situation like you described where a lot of people find themselves with a code base that
has a life of its own, its own personality for whatever reason that it ended up being created that way, right? There's always reasons that at the time that get applied, but there's just no substitute for those things. Yeah, I've worked, previously I worked in environments where we did not review every line of code and then More recently, I did.
And it's hard to imagine not having code reviews for everything anymore.
Yeah. So real quick, I'm going to throw out a couple of resources and then we'll get to picks. One is you mentioned machine learning and AI. And I have to say, we have a machine learning podcast. You can go check it out at Adventures in Machine Learning. Just go to devchat.tv, click podcasts up at the top. And it's right there, Adventures in Machine Learning.
Or you can find it in your favorite podcast app. Just do a search, Adventures in Machine Learning, you'll find it. It's got kind of a face and some artwork. Anyway, it looks really cool. And I'm very proud of it. And yeah, one of the hosts, he's a really good looking guy. And yeah, Miguel's pretty cool too.
The other one that I'm going to throw out there, and you know, because we're talking about discipline and practices and things like that. I had a really terrific conversation with Bob Martin about clean craftsmanship. And he talked about practices and Oh, man, I'm going to blow this so hard. Practices, there were three levels to it. The third one was ethics. Practicals, I think it was disciplines.
Principles, was it principles? Anyway, go listen to it because he breaks it down. And the first level was, he talks about TDD, pairing, you know, those kinds of things where, you know, like you're talking about, the code reviews kind of falls under pairing, right? And then testing of some kind, right?
under TDD, you know, and some of these other things where you're just doing these practices that get you to where you need to go. And then you have standards, right? That's what it was. It was standards. And so what are your code standards, right? That make the code the kind of quality that you have to do. And then the ethics were
you know, the kinds of things where it's, and he has the programmer's oath is what he calls it. And we kind of talked through that. We have another episode where we talked about that on the Clean Coders podcast. But he talks about, you know, hey, you know, am I making the code base better? Am I delivering for the company that's paying me for my time?
Am I delivering code that meets the kind of standards? Am I improving my skills so that I can deliver for my team? And Things like that. Anyway, it was really, really interesting conversation. And that's the kind of thing that we really need to be talking about too within our teams and with the people that we work with.
Because at the end of the day, it's not just, hey, here's the technology and the technical approach that we use to solve the problem. But it's, yeah, what are we doing to make sure that it's the right solution to the right problem? What are we doing to make sure that the code meets the standards that we have for the kinds of solutions we deliver?
And what kinds of things are we doing day to day in order to make sure that we are delivering for the company that we work for, delivering for the team we work with, delivering for the world at large, and things like that. So anyway, terrific conversation. I'll put both of those links in the show notes. And yeah, let's go ahead and do picks. I'm going to push it to Dave first.
Dave, do you have some picks for us?
Yeah, sure. So my first pick is a Pack Tool Gecko Gauge. If you've ever had to work with hardy board, which is the cement fiber boards that you put on the side of houses, then this tool is amazing. It allows you to just clamp on to the previous fiber board that you installed and then set the new one just right on top. It'll be completely leveled to the other one.
It is a life-saving tool for working with hardy board. And the whole reason why I picked this up is because I'm building a shed underneath our deck. And I'm now getting around to the part where I'm doing the siding to make it look like the rest of the house. I was not going to be able to do this job without that tool. So it's amazing. And on the date of recording this podcast, today is April 1st.
I launched a new tutorial site. So I've been doing Drift and Ruby for many, many years, over 280 episodes I've recorded on Ruby and Ruby on Rails. And so today I've launched a new training site and that is Drifting Cobalt. So you can go to driftingcobalt.com and you'll see that it's a completely satire site for April 1st. But...
Hey, if it picks up one subscriber, that's like 10% of the entire Cobalt user base. So I'd say that's when.
Wow. That's amazing. I actually did Cobalt when I first started programming, dating myself again. So this is great to see.
Nice. Very cool. I'm gonna have to... Is that a punch card? It is.
Nice. It's not a real punch card. The real punch cards were more like the... This is... This looks like a copybook description.
Yeah, your data formats and... Oh, I'm tweeting it right now. It is a good call out that we are recording this on April 1st. When you all asked me to be a guest on the podcast, I wasn't sure if you were joking or serious. Hey, you scheduled it, not us.
Fair enough. Fair enough. Yeah. All right. I've got a couple of picks I'm going to throw out there. The first pick that I have is I've been using this tool. I'm really liking it. It's called ClickUp. Now, if you have used Notion, Notion.so, I've picked it on the show before. Notion is kind of an all-in-one, how do I put it? It's supposed to be kind of a wiki slash Trello slash to-do list slash.
Anyway, it does not have any kind of automation available. And it doesn't integrate with Zapier. And so I quit using it eventually because I just couldn't do with it what I wanted to, right? Well, ClickUp has all that stuff built in. And what it doesn't have built in, it actually integrates with Zapier. So I'm really, really loving this tool.
And so I'm actually moving as many of the workflows for devchat.tv over to it as I can. A lot of the stuff's still on Trello. And that's where I wound up moving a lot of this stuff to. So it's going to take some time to move it over. But I am really, really looking forward to some of this stuff. I can actually include some of the other folks from devchat.tv on it.
And so I'm looking at instead of, for example, we have some automation that's built into Zapier that's supposed to like pick things up and send out a calendar invite and set up a Google Doc and do all this stuff. And I'm hoping that I can move all of that into ClickUp and then just invite our podcast guests as guests on the tasks. That's the only part of it I can't.
guarantee will work because I haven't double checked on that. But for the hosts and everybody else, I can actually go in and do that. And I'm hoping to be able to automate all of that stuff so that then it comes back after the episode and says, because we manually have to follow up. Hey, can we get a description for the episode and a title for the episode? Because I'm not on all the shows.
And so I'm kind of the backup on the shows that I show up for. But if I'm sick or if I'm just not on the show like adventuresin.net, I'm practically useless on that show anyway, right? I can kind of make it up and go look up the terms I don't know, but realistically, right? If they're talking about like some deep library in C Sharp, it's like, okay, what is this thing, right?
And I have to go do some research. So that's what I'm looking at doing is just automating the crap out of that. And so I'm pretty excited about that and working through it. But if it lets me automate all of that stuff, I'm going to be one happy dude. And so I'm going to pick that. The other thing that I am also going to pick is dev influencers. So devinfluencers.com.
You've heard me talk about dev heroes. That's now dev influencers. So if you're looking at kind of that next stage, or if you're in a position like Darren, where you're a developer evangelist, or you're trying to gain some kind of audience, where you're trying to get noticed. I'm putting together basically a coaching program. And I currently have five people in there.
where I'm coaching them every week on, okay, here's how you build an audience. I'm focused on podcasting. So here's how you build an audience. Here's how you build your podcast. Here's how you get people to listen to it. Here's how you grow it. And then from there, it's here's how you build it into... Some people want to do speaking. Some people want to teach live training.
Some people want to do courses. Some people want to do... I mean, there are all these options. Build their freelancing practice. Get a better job. All of those things are things that I have done out of... podcasting while I'm working on the course. But all the other things are things that I've done out of it, right? I have a book that I've written that I've sold off at the back of the podcast.
And so if that's something you're interested in, you can go check it out. But if you want a podcast about it, I'm putting that out too. So go check it out, devinfluencers.com slash podcast. And you can check that out there. You can also go to devinfluencers.com slash apply and And you'll put your email and name in.
And that's just so that some people, for whatever reason, they hit the thing on their phone, the application, and then for whatever reason, they don't get the information in. That's so that I can just remind them, hey, look, I'm filled it out. Can you come back, right? And then I'm planning on sending some emails out and some other stuff, putting some other stuff together there.
But yeah, devinfluencers.com. That's where all that stuff's going to be for the podcast. And I'm going to be talking about how to advance your career. A lot of people, they get stuck at senior developer. That's the other thing. And they're like, I don't want to be a manager. I don't really want to go architecture or whatever. I want to keep writing code. And this is a way you can do that.
So anyway, devinfluencers.com. That's kind of my thing. And that's not an April Fool's joke. Darren, do you have some picks for us?
Yeah, well, I'm going to go ahead and mention if you like Ruby and Rails and you like getting those benefits of containers that I talked about, definitely check out Engine Yard Containers. That's the next generation platform. You can go to engineyard.com. You can also on that site go under resources on the blog.
You can check out my Ruby unbundled blog where we talk about the different architecture concepts and other cool things that I find fascinating about Ruby. But yeah, so Engine Yard Containers is a great way to quickly deploy those Ruby apps, scale them up, and get some of those observability and other benefits we talked about. Am I allowed to do that for a pic? Is that okay? Absolutely.
We usually ask you to at the end where people can find you.
So that does help. I'm ahead of the game. Yep. I would throw in, I mentioned the other app land is a really nice way to figure out what's going on with your code base as well. I would throw that out there as my other pick. They have, I think app map is actually the gem. App land is a site if you want to share those across different users on your project.
Awesome. All right. Well, and then I'm assuming you're also on Twitter and Facebook, or Facebook, Twitter and GitHub.
I am at Darren Bramer, D-A-R-R-E-N-B-R-O-E-M-M-E-R. I probably need to get a better Twitter handle, don't I? That's too complicated, but it is my name. So you can find me there. And on GitHub, I have my old user ID, just letter D and then the first seven letters of my last name, D Brome. So that's me on GitHub.
All right, cool. All right, well, thank you for coming. This was really, really fun. Yeah, thanks so much for having me. This was great. Yeah, it's fun to argue about architecture, right? I love it. I love it. This is what it's all about. All right, folks. Well, until next week, Max out.