 Cool. So, thank you for coming to Let's Build a Blog with Cloud Foundry. Let's Build a Blog with Cloud Foundry. This is a talk. But what am I trying to achieve with this talk? What I want to do is try and explain what I think is the Zen of CF, right? Like, CF largely gets out of your way. And I want to show you how you use CF well, right? It's a very easy thing. We're just going to build a blog. But I hope we'll talk a little bit about how you use Cloud Foundry to build a blog and how it's different from how you might use other systems to build a blog. This is an opinionated talk. I am going to say some opinions. Other opinions are available, though not from me. This is how I think about stuff. Right. This is how I think about stuff. Today, I may change my mind. I'm open to other opinions about how we should build software. But maybe some of these ideas will be useful. So, I think the core thing about CF is the abstraction is code. Why is that? Because, actually, we use computers to solve hard problems, right? We are actually doing stuff that's hard. Sometimes we forget that. We forget that we use computers to do hard things. In the last, like, three decades, if you think about it, we have gone from biasses to people on the moon to driverless cars. Then off to the right of that is like, you know, Fortnite and iOS apps that let you order ice cream to your door, which is a thing my girlfriend does. How did we do this? I think there's two things. There's two things that have ever worked that have letters with the same size of chimp brain go from biasses to men on the moon to really annoying computer games that people should stop playing. Those are removing accidental complexity. These are literally, we've known this since the mythical man month, right? Like, Brooks, 1983 or something. Remove accidental complexity. As in, the less you can focus on the problems you cause for yourselves, the more you can focus on the essential complexity of the problem you're trying to solve and use good abstractions. The reason we can build a driverless car is we don't do it in assembly language and C. We have higher and higher level abstractions. That's accidental complexity. That's mythical man month. Fine. Let's talk about abstractions for a second. I just want to give an analogy. C, we're going to play a game. The game is called operating system or web app. I say a language and you say whether you should use it to build an operating system or a web app. C. Let's see if you are right. Well done. Okay. Let's play another. Ruby, operating system or web app? Yes. If anybody is building an operating system with Ruby, come and talk to me afterwards. I think I can help you. I think. So the point is that different languages have different sweet spots. It doesn't make C better and Ruby better. It makes C better at a certain thing and Ruby better at a certain thing. Different tools are suited for different jobs. That brings me to Cloud Foundry. Cloud Foundry is a high level approach that doesn't try and solve all problems but tries to solve some problems well. It's a high level abstraction to try and make you faster. And that abstraction is code, not containers or orchestration or pipelines or stateful stuff, code. That's what I want to try and show you. Plus services, right? Because you do need some states. The trick with states is to make it someone else's problem. So let's build a block. This is structured as like four opinions punctuated by a bit of coding. Opinions could also be rants. You have heard the first one which was on accidental complexity. Let's build a bit of code. This is where I have to like do a font size check. This is too big, right? Is that kind of visible at the back? All right. So let's, what should we call our blog? Call it blog. Whoops. Thank God we haven't had an inventive audience on the peak of their naming abilities. So how do we get started writing a blog, right? We're going to need a docker file. We're going to need some deployment YAML. New. Main.go. Package main. Funk main. It's not called package main. Package blog. So what I'm going to do is build the back end, right? I'm just going to build the back end for the blog, right? So I have what's called a snippet. Let's me do that. Let's put it in data blog.json. And what does json, what does blog.json do? It's going to newencoder.incode. And then we'll give back some, the posts, right? We'll give the list of posts back. So let's do that. Working backwards. And what would a post have? It would have a title. Oops. I have no idea what I just did. Typing is hard on a MacBook. Titan body. Cool. Who would like to name our blog post? What's the title of our blog post? The treasure trove. This is what's called audience participation, friends. Great. And it says, in the treasure trove, we will find a Jools. Thank you. I approve. So why doesn't that work? Is that it? Computers are hard. What's wrong with this? What's wrong with this sentence? That is. Ooh. Ooh. It formatted. That probably means it worked. Yeah. Good. So that will print out our stuff, right? And how do I, oh, I need to do a listen and serve, right? But first, like, so start thinking, how do I run this? How am I going to test this? Listen and serve. OS.get port. Neal. Done. Okay. So how do I run this? Go run. I hope people know enough. Like, if you don't know, it doesn't really matter. It's just the language that I know. Port equals, let's say, 8080. Go run main.go. Oops. Oh, I still have that running. Can't run non-main package. Never live code. Oh, we have to create a go.mod file. Because we're not in a go path. I think it's called module blog, is it, I think? Does anyone know how you write these, like, go.mod files? These are new. Don't really understand them. Go.mod init. Aha. Here we go. So, yeah, you get rid of go.mod, and you say go.mod init blog. Cool. This worked when I did it before. Module blog. Can't run non-main package. We might have to put it in a go path. That would suck. So here's our thing. It's in package blog, right? Look, this is on you as much as it's on me if we get this wrong. Go.mod init. Let's do it the full way then. Do I have to do this? Oh! You are, yes. That is, that is embarrassing for everyone else. Yeah. There we go. And that is why we do not live code. Right. So if we curl that, curl local host, 8080datapost.json, datablog.json I did this time just to mix it up. Great. We have some JSON. Good. So that is our back end. What shall I rant about now? Microservices. All right. So we're going to talk about microservices, because they are the hot thing. Here is the flowchart. This is what I call the microservices flowchart. I told you there are opinions. If you are less than a two person, two pizza team, that is a team that you can feed with two pizzas, microservices, not for you. You've caused complexity, you've caused complexity, you will not get, in my opinion, enough back from doing that. If you have, there's a proviso as well, if you have more microservices than teams, so if you have five teams and 50 microservices, you are probably not getting that much value from your microservices. There is an overhead to microservices, which is absolutely worth it if you can only solve the size of problem that you are solving by having more teams than people. Because within a single monolith, if your team can do pairing, do TDD, do anything like that, you can manage that. If you need to scale up, that's where microservices are useful. So in other words, if you cannot do it with one team, that is when I think you should use microservices. But to fake out a good reason to have a microservice, let's build a UI. So what we are going to do, we are going to build a UI for our blog, we are going to use a language that I like to call React, because it is called React, blog UI. So for anyone who just joined us, we have took a poll of the room to decide a clever name for our blog, and we came up with blog. So we are going to create just so. We are just going to create a React app. Just create a React app. One of the things I want to try and show you is most of what I should be doing, if I am building something like a blog or like most things, is just writing code. I am going to use the programming languages test suites, I am going to use the programming languages deployment tools. I am not going to start spinning up containers and stuff at this point. I am just going to run it. So we have got our blog and this is blog dash UI. And we can edit our app.js. So we are going to, this is going to be ugly. This is not going to be, I am not going to do some CSS here. I am going to do posts.map. So post.map p. And inside you get a post and you get h1p.title. And you get the body. p.body. Div. Div. Good. Does anyone want to spell check me? See, that was an intentional mistake to see if you were paying attention and you were not. Come on, folks. Cool. So post.map. We need to make that post thing. And let's start off by just like creating a fake one. So we will just do posts and title, high, body, there. Right? Const. Yeah, see? You are getting there. You are getting there. We are learning as we go. So how would I run that? I do yon run. Yon start. So this will be just the front end. Just coding it out. And we are imagining that we are, yes, why not? Why not? We will have ports, whatever. So we are imagining we are two separate teams. So I am going to develop my UI reasonably separately. Start the development server. Does anyone watch Crystal Maze? Start the fans, please. Is that just like a UK thing? All right. It says, hi, there. Good. So what we want to do now is integrate these two things together. So how do we integrate these things together? There is a great thing for React. You can do this. You can do package.json. And we can add an element called proxy. And what proxy does is it says, when you access slash whatever, forward it to something else so that you can integrate two things easier. So in a browser, you can't directly access a URL for security. So we are going to access local and React will just proxy it. So we will use local host, local host data. And I think we did it on 8080. So what this will do is anything that goes to local host, it will forward it over to local host 8080. If it is not asking for JSON, it will forward it to 8080. And what we want to do is we want to now grab it from that URL. So we want to grab it from the data URL. So we can build a little use fetch. So function use fetch URL. And so to do a fetch, we want state and set state. This is this new React hook stuff which is super awesome. State. And we need to do a use effect. It doesn't really matter if you know what I'm doing here. So I do a use effect and I say fetch URL. Then we get the response. And I'd like the response.json. And then give me that JSON and set state with the JSON. That looked about right. Return state. Cool. And with that, I'm going to say use fetch. And I want to fetch data block.json. I think is what we said. Spell checking as we go. Is that about right? What's wrong with this? It's really hot because you can't see the end. So we've got fetch.then, response.then. That all looks right. All right. Who helped me last time? fetch.url, then response, response.json. Then json, set state json. Yeah, one more close brackets, isn't it? It's literally the hardest thing in programming, isn't it? It's just like brackets. Oh, of course. Right. So function. I think that should do it. I don't think we care about anything else. State, use state. We need to declare it because imports, use state, and use effect. Good. Right. So we now have a UI. I'd really like to get to the cloud foundry bit soon. We're close. We're close. So let's boot that back up. So we've got our blog post running on 8080. We've got our thing. We should be able to load it up. Well, hello. And did we get anything from fetches? So now we can debug. One thing that's quite cool about this way of working is that you just have all your native tools, right? This isn't running in a container or doing anything funky. So if I look at, ooh, lots of stuff happening there, we're going a little crazy. I have a feeling we're getting a ton of 404s. Let's see. I'm running out of time. We might, might have to go to the next step. You can't do it. You can't do it. So let's look at the console. And I want to look at what's going on in the network. I'm looking at XHCR. Oh, so we've got the blog back. We've got our blog posts. There they are from our XHCR request. But it didn't make it into our thing. So let's have a look. Why isn't that working? We've got posts which use app, post.map. All of this looks good. Did a set state when the JSON came back? Can we turn the state? Does anyone know why that's not working? We got the state. We know it came back because we saw it come back. We did a fetch and we put the response. We've got the JSON. We've got the JSON. I mean, we can do a bit of logging. All right, let's have a bit of logging. I think we do not have enough time to skip. We might have to skip to the next bit. What's in our logs? So we even logged it. Got all the way back. Oh, wait, you know what I think it might be? Oh, this is sad. Very sad. No. It's looking for lower case. That is annoying. So I can put it back and what I will do. So this is actually okay. All we actually want to do is edit our main.go. What we should of done is put struct tags on here, right? That's not the one. JSON title. Good. JSON body. Good. Good. Cool. Yeah? Now, everyone just compile that in your head for me. Yeah? How confident do we feel? Yes. Boom. All right, great. So we now have a UI. I want to do a little rant. Containers. I think what a lot of people do right now is start putting this in containers. We are not going to put this in containers because it is a go application and a JavaScript application and there is nothing magic about either of those two things. Here is my container workflow. By the way, I work on containers in Cloud Foundry. I run the garden team in Cloud Foundry. I love containers. Containers are brilliant. I just don't think most people should touch them most of the time. You don't actually need them for most things. If you are a pass, you need containers. If you are CI, you need containers. So by all means, set up some CI to convert all your code into containers, but most people should be able to see F push or something analogous. Are you coupled to an OS? This is another good reason for a container. If you are doing something that is genuinely coupled to an OS, it matters what OS you are running on, then you are going to have to decouple yourself from an OS and have a custom Docker file. I would argue you should try not to be coupled to an OS. If this seems crazy, let me point out, every day we load JavaScript via our web browsers and it does not come packaged with a browser to run that JavaScript in. It works fine if your language is encapsulated. Go and just make static binaries. They will run in anything. Java literally runs in a JVM. We don't actually need to isolate ourselves from the OS if we write simple code. So just push code. Lock in. If I don't use Docker files and stuff, I will be tied in. It is just code. What I have written so far is just code. I didn't touch Cloud Foundry. I could add a Docker file to any of that stuff. Now let's do a CF push. What we are going to do, we are going to first, we are going to push our blog to the interwebs. Let's do it here. Let's have this one. It is surprisingly difficult to do it when it is really big text size. I am not going to push it as JavaScript. I am going to build it. I am going to do a yarn build. What that does is it packages it because all the various MPMs are enormous. If I do a CF push it will upload all of this JavaScript stuff. I am just going to build it. Then we end up with this build folder which has inside it all the stuff that I need to push up. If I touch build static file, that will tell Cloud Foundry that it is just static, just serve it with a static thing. I can do a CF push, blog, and I will say dash P build. That is it. That is all we need to do to run that on the cloud. It is now going to run on the cloud. That proxy thing will no longer run. What we are going to have to do is run our back end, our go app. We want to run that on slash data. Anything on slash data, we want to serve the go app instead. Luckily, we are using CF. That is quite easy. I can do CF bind route. First I should push it. I can push this application. Let's create manifest because it is go. I do not have time. I am going to skip it. You use bind route. You bind the route of that go application to slash data. You now have those two things communicating. I want to have enough time to get to the next step. I am just going to get to the next step. Opinion for state. I think this is probably the most important thing that I want to say. I have three minutes. What is wrong with it? I need you to do a visual picture because these are not the correct slides. What is wrong if there was a picture? If you go to any Kubernetes website or Docker website and you look at a picture of a simple app, you may have to Google it, what you will see is a MongoDB or a Redis plus an engine X plus your application server. What is wrong with that picture? Do not push Mongo to cloud. Do not push database to a cloud. Unless you want to be a DBA, use a service for that. You should be pushing code to a cloud. State is bad. State is bad. Why? Because state is the magic trick that turns cattle into pets. State is why I can't throw away any one of my replicas that I want. When something goes wrong, if there is state, I have to worry about it. That is why you need to back that machine up. You need to investigate when it goes wrong. You need to think about how I scale that up and down because you cannot just add instances easily. State is hard. What do I do about state? Make it someone else's problem. That is how you are able to move fast, develop iOS apps that deliver ice cream to my door, which is important. Use state. My flowchart is are you a DBA? If so, state is fine. Would you like to be a DBA? If so, state is fine. Otherwise, no. How would I add state? I don't quite have time to do this. What I would suggest is for example, I use IBM pays my bills. If I go to IBM and log in, I will see that is the nice thing about a Cloud Foundry system. I see a catalog of services that can do my state for me. If I created one of those services, I have created one here, then I can just bind it to my app. I say CF bind service and bind that service to my app. My app will get an environment variable with the username and password for that service in it. That is how I do state. If I take my main.go and get the username and password, quite a good one is, in my opinion, Cloudant, but use anything. The nice thing about Cloudant is you can just store JSON stuff in it. You just store JSON documents. You take the blog post that you want, you store them in Cloudant, you bind it to your app, and you will have an end-to-end blog. All you will need to do in your development process is code and then push. No containers, no deployments, no orchestration or scheduling or anything else, just your actual business value. That is the edge of my time. We didn't quite build a blog with Cloud Foundry. Nevertheless, this is the Zen of Cloud Foundry according to me. Number one, avoid accidental complexity. If you need to do some low-level stuff, you're going to have to do some low-level stuff. But try to operate at the highest level that you can because your problems are complicated enough. If you can spend time either on container orchestration or improving your login flow, making your code faster, adding a feature, prefer the latter things. In my opinion, most people, the abstraction should be code. Cloud Foundry is one way of doing that. If you're building for something like Kubernetes, build some CI that makes that process repeatable. Microservices are fine, but don't go crazy. If you use CF, it's quite easy to run a lot of microservices, just CF apps. Don't run 10,000 microservices unless you have 10,000 teams and consider whether you need 10,000 teams. Most importantly, state is bad, so make it someone else's problem. That's not building a blog in Cloud Foundry, but at least maybe we got to a little bit of the Zen of Cloud Foundry, which was the more important point. Thank you very much.