 All right, there we are at 35. Hello, everyone. Thank you very much for coming to my talk This is called keep your heads in sync content delivery across a decoupled presentation fleet Everything here is kind of obviously gonna revolve around decoupled Drupal which maybe you stop by my talk at triple con global it's something that I talked about a lot here when I do speak in triple camps and things like that and In this talk, I guess I'm going to be expanding a little bit on some of my past topics where instead of just having a single site consuming content from Drupal sort of what goes into maybe the something a little bit more realistic where you have multiple applications that are all consuming that content API So let's go and get started tangled in cords a little bit here. So hi, I'm Chad Carlson. Here's picture of me. I'm a dev rel engineer at platform.sh where I primarily work on our public documentation and a lot of our example projects and templates that you'll get started with when you deploy with us for the first time. One of the topics that I spent a lot of time with is this decoupled and headless sort of space that's been getting really popular in the last few years. And so Drupal and Gatsby has been one that I've worked with quite a bit. And so that's what I'm going to touch on in this talk. So we're going to talk about decoupled Drupal and in particular what this sometimes will be referred to also as headless what that pattern really means You'll probably be familiar but if not we'll take a look at some of the basic ideas in decoupling Drupal and what that looks like for deploying decoupled Drupal on where I work at platform.sh And we'll take a look at how it opens up these content APIs like I said to be consumed by more than one presentation application. So we have less of a headless situation than a kind of Hydra mini headed situation. And then we'll finish up with some of the things that you can change on the Drupal side of this fleet that we're going to start building and how we can keep all of our presentation apps in sync with the same content all the time. Since that's got to be got to go hand in hand with this entire situation multiple presentation apps with the same content but we don't ever want them to be out of sync for when things are published. So let's go ahead and quickly take a look at decoupling itself. So if we have Drupal proper to start with we use it to manage our content and then we can customize the front end to have we see fit with things we write ourselves or community themes and plugins. And anytime a user visits our site they're only looking at our Drupal site they we have our content managed in the back end by our editors and authors and everybody in our editorial team, but our users are actually visiting the Drupal application itself. And there's nothing wrong with this approach it's powerful and super extensible and but it can get labeled as monolithic in this conversation in comparison to decoupled. And that other way of doing it, it's pretty popular now it's been getting more and more popular. It's the way it's sort of this subset of the microservices pattern so instead of offloading all of your responsibilities to miniature applications that are taking care of some aspect of your larger application of payment processing or of handling some aspect of the API. We're really just concerned with two apps of front end that is controlling presentation responsibilities. And that will usually be something that's written in JavaScript a popular framework like reactor angular or in this talk I'm going to focus on Gatsby just because that's what I have the most experience with. And then we have our back end application that is managing all that content so we're going to have Drupal in the back end. And we are not going to rely on themes or any part of Drupal itself to present that content to our users they're never going to visit this Drupal site. They're only going to go through that dedicated front end application to view the content we write on the back end. There's a lot of touted advantages to this pattern. You can have dedicated teams for the front end and back end sides of your site with fewer responsibilities that each of them have to be concerned with you know can better able to track down a bug on the front end side if that's all that they're concerned with it's very clearly a front end bet front and bug as opposed to something that might be going on with the API itself that's being served on the back end. And ultimately the idea would be we have dedicated teams they don't have to be as concerned about what each of them is doing only the common language that they use to speak with each other through the API that Drupal is serving and that Gatsby is expecting and so that each of them can collaborate together and build a lot of cool things together by by having that segregation. And that does depend on this API being abstract. And what I've become interested in is you can keep it abstract enough not just to be able to switch out your front end at will which you know Gatsby is very popular but something else might become popular or better suited for what you're trying to do on that front end and you have an abstract enough API you have the ability to switch things out. But you can also have a lot of different kinds of frameworks for many many different presentation apps on the front end that are consuming the same API. So I think I said this already becomes less of a headless situation in a many headed situation. It seems a little bit closer to what the goal of this seems to be I could have very I could have a lot of different teams that have very different concerns about how my content is presented it could be on a lot of different types of devices whether that's just the desktop mobile distinction or some Internet of thing device or gaming system or it could be as simple as I have a bunch of content that I'm serving up for a company but I have a lot of regional divisions for my company that their site has to look a little bit differently and they have content specific to just that region but otherwise they're going to get releases and information from this central in this case is central Drupal content store. In that case they can be segregated by a lot of different sites consuming that content. And it's something that people here are interested in it's it's becoming a bigger thing with Drupal if you did attend Drupal con global there were I think 11 or so different talks and summits all around this decoupled concept and topics around deploying it what it's like actually managing a to application decoupled situation many front and apps like I'm talking about here at scale. People are interested and are coming up against new kinds of problems as it becomes more popular and also during global became a new strategic initiative. Specifically around exposing menu items in this API that you're building out for Drupal and just all around becoming a better place to support all of these different JavaScript frameworks and libraries that people would like to use so it becomes an attractive experience over choosing something like a WordPress backend or a a a dedicated headless version of this API and there's a lot out there in all kinds of different languages PHP JavaScript. What is it that's going to be needed to make Drupal as good as it can be to to handle this new found interest in decoupled. So it's relevant it's going to grow and hopefully this this talk can shed some light on what's so interesting about it and how it fits into this many head perspective on it. So I work for platform as H what's it like what's it look like deploying this decoupled pattern on platform. A lot of the times that you'll see decoupled things will be completely segregated I mean that's kind of the the heart of the concept right is to have responsibility separated so we're going to have these applications in two entirely different places. I'm going to have my Gatsby app on Netlify and I'm going to have my Drupal app on anywhere else that but just the concept would be that they're not interacting with each other other than let's say hard coded environment variables on each of those apps that they know where they are. At platform we have a kind of configuration setup where it supports multiple applications in a single project. So essentially the way that we recommend people set up decoupled is we have a single repository that contains the code base for let's say two apps to start with both my Drupal app and my Gatsby app. So I have a sub directory called Gatsby everything to do with how I'm handling my dependencies and the application code for Gatsby in there and then I have a completely different sub directory for Drupal that's everything contained there. But when we deploy them based off of our configuration they end up becoming two separate application containers on this virtual cluster that can then communicate with each other over an internal network. And that becomes great because you could do things like I don't want Drupal accessible publicly at all I want it to only be accessible over this internal network to Gatsby or a lot of what we provide people when they deploy any kind of application is that each time you create a new branch you get an exact copy of those same infrastructure configuration and code on that new branch, you know, or associated with pull request. So, as both of these teams are developing Gatsby and Drupal alongside each other. They're getting an exact copy of both the front end and the back end in their little environment they can play around with. And it's all in one code base so everything is highly visible and as collaborative or, or maybe the wrong word but it's it's isolated and segregated in terms of responsibilities but everything is very visible between what both teams are doing because it's in one repository. So here is the example that file structure here, most of our configuration, or sorry, all of our configuration revolves around these types of files these three here in the dot platform hidden sub directory. So roots handles how requests are handled. And services say I want this version of this database accessible from this string this this service name key. So the application ZMO file allows us then to define each applications build and deploy for each of these apps here, and I think I have a snippet for Gatsby hopefully you guys can see that have it named Gatsby, it's going to be part of my library that in that app container I want no JS 14 so I will always have the same version of no JS every time I branch off that environment and work on that same application. And I have my build and within this internal network I have access to my back end Drupal application my Drupal container over this relationship called Drupal so anytime Gatsby needs to pull that content during its build. It can look at that relationship there and access that API. And inside this configuration file I say how I want Gatsby to start so it's going to be similar across all these JavaScript frameworks, I can do a normal build and start what I have built into my public sub directory. Or I can set a live development server or a development server on one of my development environments so that gives us some of this live preview and incremental build functionality that's also becoming pretty popular across these across these frameworks, and you end up with something like that so this is my Gatsby front end displaying the same article on my Drupal content back end being served by the Drupal API. So that's pretty quickly the decoupled idea how you can start to do it on platform SH and still we're restricted to depending on who you ask it's decoupled or it's headless or it's a single head. But let's try and direct this to the many heads idea that I brought up earlier. So it's not headless it's many headed is what you're opening up to. Because my, my, the reality of the situation is I probably don't need that content just on one site. The app, the use case is going to be a little bit different depending on who you're building a site for. But if you have either the examples I said before, many different regional sites, many different devices that have different needs in terms of how that content is presented. You potentially have 10s of different sites that all need to have the same content presented for your users in this different way. You need to support all these different teams collaborating together, working on those individual apps. And in the end, one thing that I've seen as people do stuff like this at platform or customers is it becomes a really good model for experimentation. So if we say the example of a company that has a lot of regional sites, they have a lot of content on their back end Drupal site, and each of these front ends is consuming it. So let's just say in the first in the simplest case because it's little I'll talk about a little bit. They're all Gatsby front ends. And one of these regional sites is getting content and there's some upstream template for how they build that Gatsby site. But then they try out some experiment in their region of presenting the data in a certain different way, or exposing newly added content in a banner, whatever the experiment may be. So if this is a goal made to that region, it can create this feedback loop where they say, hey, we've we've measured and observed that this campaign really worked. And the rest of the company or the company up above them says, yeah, this did work. This is a part of the upstream and now each of the ones in this fleet of Gatsby site is going to implement same strategy, because we have this measure to it, and it can be leveraged by this sort of pattern amongst this fleet of presentation apps. And that's great. That's obviously a great. It's great to have any sort of source of feedback to experiment like that. The challenge becomes, okay, we're displaying the same content. How do we keep everything in sync across all of our presentation apps? Yeah, I can get the data but let's just say I don't want to create a situation where one regional site has a new post with some essential customer information on it, but the rest of my apps don't. So how do we control the fact that a new piece of content gets published? I want all of the apps to now display that content, no matter device, region, whatever the case. So in the configuration I showed before I could keep adding sub directories to my repository for all the regions, all the front ends that I want, but we might want to enforce some greater segregation and we might run into resource issues as we keep adding more of these applications. So the approach I'm going to show here is more what you're traditionally used to. I'm going to have a Drupal content store on one project and it serves up the API. And then each time I want a regional site, something for each new device, it's going to get its own project and it's just going to continually look at an environment variable, see that's where the Drupal site is and continue to or it's going to consume that content during its build. And so that gives me a fleet of Gatsby sites. They are entirely independent in this case. They have their own teams and everybody's working together to do this experimentation feedback loop I talked about, and they're serving the same content. So this is just a screenshot of what that looks on platform, named for high visibility, you know I have two Gatsby sites that act as my front ends and I have a Drupal site as my back end content store. So we want to keep them all in sync. So platformer sage exposes this API that you know our API is public and that allows you to do things like use our CLI to create new projects and initialize them with an upstream template, but you can begin to form your own tooling to get all these projects to communicate communicate with each other over their webhooks. So let's try piecing something together. One of the interesting things that we've added recently is this thing called source operations. So if we look at the middle snippet here, you see my mouse. This is the syntax for this and this exists in the same applications YAML file that I showed earlier for how Gatsby gets built and how it communicates with Drupal. And so what this is going to do is in a separate sort of build container, when this is triggered, it is going to, in this case, force a rebuild of Gatsby. So if any of you guys are familiar with that, if you have a development server for Gatsby you can ping a refresh endpoint and it'll get the latest content from whatever you decided is the source for it. But on platform rebuild these read-only file systems, we build these build images based off of your configuration and your app code. So we kind of need to trigger a full rebuild to get the latest Drupal content. So this would be one way to do it. Inside this separate build container using this source operation, which effectively kind of extends our API. You know, you can't just add a variable to your project with our API. Now you can trigger rebuild. So that's what this operation does. And so we add a variable that includes this Drupal backend URL. And at any time we can use the CLI and run that source operation to get the latest content from Drupal. So we've got the trigger across our fleet because this command can become part of the upstream that every new front end is based on. So I can trigger at any time my whole fleet to update to the latest content that I have on Drupal. Okay, so that's our dummy commit to do that. And the simplest way to do something like that is take our Drupal app and give it a cron job. It's not completely real time when there's some new content, but I can say, hey, every day at 10am is my published date. You know, there's, that's what I'm going to set it as every one of my front end applications is going to get the latest content. They're all going to say, oh, it's published at 10am every day. And so I can put this in that same fml file for Drupal in this case. And every day at 10am run this little script here that says here's my list of projects. You know, I have two project IDs, and I'm going to trigger that source operation on each of them and rebuild those sites. And so that's not a bad way. I mean, it's like I said, it's not a complete trigger for when a publish occurs, but you at least have a publishing schedule. Get it in before 10am, like the old, you know, get it in before the newspaper hits the press before it you actually have to print the newspaper again before 10am. It'll be out for tomorrow. So this is one way to do it. And this is what I have here is the cron publishing method. Another way would be to include the trigger in Drupal itself. So we can create a custom module that uses this hook entity type update to then get a CLI token from the environment and read in the same way I have a list of projects here in this bash file that's just in an array inside this script. I have instead a, where's my mouse, a fleet JSON file with the same list of prop. Sorry guys, the same list of projects in that JSON file, and it's going to go through that and say hey for each one of them get the project make sure it exists, and maybe on a dedicated environment if we'd like it to work that way. So this gives us like a more effective trigger for making sure that all of our fleets every site in our fleet is in sync. This one's pretty cool. My, my colleague actually came up this one it's not actually in the blog post article that I included there this is a recent development here. I can verify the project and the environment trigger the operation. And now I have this fully coordinated content presentation fleets make my edits on the back end Drupal app. And each time that update occurs, I'm just going to trigger rebuilds on my front end apps. And of course, you might want to have some greater control on this one too. But here I have an environment check. So a good way of making sure you don't have some unexpected rebuild on your production front end app would be to say hey I only want to call this source operation on a update content environment that we didn't update occurs we can merge. And otherwise it just kind of stays open and sinks from production all the time. But we won't have unexpected rebuilds on production but we'll have some alerts set up like we have another notification system that we can use to send slack alerts for when an activity completes. So we can say hey when this source operation completes on this branch, send me a slack message for the individual team that's responsible for that presentation app. And then they can kind of go oh yeah this is just the normal rebuild that I was expecting anyways. So I'm going to go ahead and merge. So this is sort of how I see the multi headed situation. We have editors and authors that are free to focus on content. And the same promise for each of these decoupled front ends but in this case, many many front ends we have many teams have a lot of different people working together to present the same content to feedback on each other on best methods of how to do that for the different regions or devices that they have all supported by this common API setup by Drupal. And from there we can just focus on our jobs. We can trigger updates in the background and everything can kind of be kept in sync the whole time. And, oh, in the collaboration upstream. So yeah, that is, I believe the last slide here. Thank you all very much for coming. I'm happy to answer any questions you have about platform or about this idea in general. I think we have a Q&A section on the chat here. But yeah, thank you very very much. So yeah, I get what you're saying, I think that's that's a lot of what gets opened up for this source operation thing because it creates an endpoint to make a modification on the code base which we would normally limit to, I mean, any any change that happens on these environments has to be done through commits. So we do that through an integration or a direct commit up to our remote. But this then gives you an endpoint to do things like hey I want a source operation that triggers dependency updates on this project so you can have a lot more control over what all these fleets do that may not have anything to do with content but this becomes another fast set of changing that front end site. Thanks Evan. We got any questions in here. How would this differ if they weren't all Gatsby is the source operation, the same. Yeah, so like I was saying, our building an application gets tied as a per commit build. So the idea then would be if I have my master environment, the only way to change that image that deployed site is to make a commit on it that controls unexpected things happening in a lot of different ways and so we would recommend you open a new environment, you get a clone of production data and of that production code that then gets deployed to its own site and only through a merge does that go into production I mean we're pretty familiar with this idea. So if I had a front end react site or anything else that was consuming that content, so long as a part of its build stage, there was a step that pulled content from that back end Drupal application. So long as it requires a rebuild this is a totally generic command that would allow you to do that. You just trigger rebuild on the front end, and it makes that same call to Drupal I don't see why. It couldn't be used for whatever your front end happened to be. Hey Peter, no we're not using Docker for deployment at platform all of our containers are based off of LXC, and we don't have Docker support. But you should check us out. It's, it's, I think a lot greater simplified configuration for handling all these environments and setting up builds for a lot of different kinds of applications. So you had a root of gamlify I was wondering if you had an easy and smooth way to root the back end you preview. Are you saying giving you a preview within like if the normal builds in Drupal preview situation. For that question, you would have to set up a specific start command to enable that kind of incremental build, and it would just be in that case, getting in there to figure out how that preview builds or that preview redirect happen inside of Drupal itself to get you there and pulling it from the current environment. It's not hard at all to say I'm on this current environment. I'm on the URL of the current front end, in which case you could very easily set that up for any environment you created. No problem. Yeah, but nothing about this is something we're offering a platform other than this support for multi app but I'm happy to talk to you more about it if you'd like. Yeah, come by the booth I'd be happy to talk about it. Thank you everyone for coming.