 Before we get started I have a special request if you're on camp and in the possession of a steel brush for cleaning grills Please join us at the 2342 village next to the hack center at 8 p.m. And you'll be eligible for some delicious steak first one to show up wins Now a quick learning opportunity before we get started So don't put dates in the titles of your talk proposals during a pandemic because you know the events might not happen. So Yeah Let's get started. I think the title gives it away pretty well I'm up here tonight to show you how to build modern and robust web applications without writing any JavaScript Apparently that's a topic of interest here so First things first JavaScript has merit. It's not like I'm bashing on JavaScript or anything I'm also not saying JavaScript is terrible. I'm also not saying JavaScript code is inherently bad But I'm saying I don't like to use a second or a third language when I'm programming or solving business problems So yeah, the thing is it uses JavaScript, but we're not gonna write any of it So everything is already done. We don't have to take care of it and we won't notice it's there The talk structure Really quick. I'm gonna start with three questions for the audience introduce myself and tell you why I'm here or at least what qualifies me and How you can avoid huge pain then we'll continue with a practical example and some semi-life coding and Well, the last part is going to be a risk controller for the set project we're about to do and I'm gonna have an off-stage Q&A afterwards because probably the I'm gonna run out of time. So yeah, I'm gonna do it outside somewhere Some more things upfront you won't learn a new programming language today The syntax is pretty easy to understand if you're if you know proficient in English then you probably understand everything we're about to do But you will get the interest in learning a new language that much I can promise you or at least I hope Because you can achieve so much with just so little as you will just witness and the syntax Really if you're proficient with Ruby, then you'll just probably understand most of it right away If you have questions Please write them down or I remember them until the end of the talk as said there might be Well, there will be the Q&A outside the tent. But yeah, just keep on till the end. Please. Thank you So little audience participation who here has written a web application just by a show of hands All right, that's about everyone Who opted for a refresh rather than updating the DOM or writing JavaScript? I'd say well, all right good How many of you wish to have not having written JavaScript or having to debug it? All right three quarters, I guess All right, so why am I here and who am I? I'm Franz. I'm 37. I work as a freelance IT consultant for almost 20 years now I'm located in Nuremberg, Germany. I'm a certified Something and doesn't really matter. I got my swing badge, too I've consulted for multiple fortune 500s in the US stock listed companies and done paid projects in over 25 languages Which usually means more than the typical hello world people don't pay for that It's more about 30 now. I stopped counting at the last talk. I gave like seven years ago. So who knows I've been building distributed back ends for quite a while now. I started out with Scala I'm a lift web committer still to this day even though I don't do anything anymore, but you know Anyone remembers four square the check in app. Yeah, that's built on with lift web. So you've used my code. Thank you Then I got heavily into go lang when I got sick of the JVM and learning its special intricacies over the years Yeah, and then I moved on to elixir slash Erlang in 2019 Meet the Phoenix elixir framework. That's at least how you're with the huge pain part. It's written in elixir How many of you know the language elixir? All right, so four people. That's fair. All right It uses the Erlang VM at least so it feels like Ruby to a degree So if anyone has tried Erlang and not gotten along with the syntax, I urge you to try elixir Erlang is really really good at message passing not parsing but parsing and pattern matching so elixir is too and It's really good at handling huge numbers of connections So if you're doing web projects and you need to scale out later, then it's a lot easier doing it this way It comes with a built-in distributed pops up. So you can do fancy stuff If you have an Erlang cluster or you decide to scale it up into a cluster Then you automatically get a distributed fault tolerant pops up. I mean, that's great And it's a functional language Well elixir itself and the whole thing is even driven. So, yeah, it's it's pretty awesome and any regards because It abstracts away anything you do with JavaScript. Really. I haven't written a line of JavaScript in almost two and a half years so I'm happy about that and It comes with out of the box web socket transport and HX fallback. So you don't really take care of any of the fallback measurements or implement yourself anything it just goes itself and Yeah, it falls back to get post-request of JavaScript is disabled So if you know one of those guys that wants to disable JavaScript most of the stuff is still gonna work except for some minor things that will go about later and We are going to talk specifically about the feature called life view and It's server side and rendered HTML. Well, most of the HTML is and But the difference is Through the this the server always knows which variable is bound where in the dawn so, you know, you can easily update it without you actually having to know it and Then it sends it diffs to the browser over web sockets or Ajax So your web page gets updated but not, you know, the entire page or anything. Just the snippets that change That's pretty efficient and people already wrote browser games with it like 60 plus FPS. I mean impressive for something like that So The thing I like about it is I can really just write business logic and not solve all the other problems that have to do with Whatever happens between the browser and my server that all of that is taken care of so you can really just focus on whatever you want to build and I think that you know makes for a lot of fun and gets back to actually solving problems and not, you know Solving problems to solve another problem and then solve another problem. So we're actually working at the things you want to solve And you don't have to care a thing about when event X happens. I have to update element XYZ in the dawn. So and When is disabled? Well, I don't have you know We don't have to write the fall back ourselves. I mean by now I mean how many implementations are there out there? So we shouldn't have to write this on every other web page ourselves How does the whole thing work? So I said firstly delivers a render HTML as every web server usually does Guarantees that most stuff works even when JavaScript is turned off but if JavaScript is enabled then the web socket connection takes over and It ensures that it automatically Rerenters and updates all the right parts of the web page which is nice because we don't have to do it and If JavaScript is disabled well and everything except the real-time streaming updates and stuff like that is gonna Not work. I mean, you know So the server knows all the places it renders variables, so it knows which parts to update This is a pretty easy example. I don't know if you can see it from back there or but Generally speaking, you have you know a snippet and it replaces a variable So your server site should know that there is something that could be updated. That's the easy code part But we're gonna explore it in the in the live coding in a second so the simple demo project I prepared is Web-based thermostat that is going to be live updating Why because it's in the web frameworks documentation so should you decide to Learn more about it. You'll know at least some of the bits that you'll read about in the documentation and can relate to it And it's it won't be super foreign to you. So at least you've heard that and I decided to add pops up to it so I can show off the liveliness and how easy it is to implement So we're gonna create a new project in a second. We're gonna add a database model and a migration for persistence We're gonna add two buttons to increase and decrease temperate decrease temperature and write 40 lines of code in total And add a couple of tests for a new buttons Yeah, that's terrible. That's super terrible so we're basically now creating a new project and Pardon me. Ah, there's greens. Awesome. All right. So what it's doing now We're basically creating a new project and it's downloading all the dependencies and compiling all those mix is basically elixirs, you know gem or make or combination of both and so yeah, it does a lot of things in the elixir world So now it's compiling. This is actually the longest step in the whole well where I have to wait for it the font size That is really bad right now Pardon me. It's all right. Yeah All right, so it done, you know creating the project. I mean the half of it is going to be on the browser side So on the right side, so we're gonna see it We're creating the database right now and All it we're basically doing is I'm just removing a warning that's coming from the new compiler version that I'm using and What we're gonna do is basically create the database start a new server and look how the how a basic elixir Phoenix project looks like That's happening right now. I Hope the browser. Yeah, that's good All right. I hope that's clearly visible for everyone. That's basically how a standard elixir project looks like So what we're going to do now is use a generator to a crop generator to generate a context called measurements and Database model called thermostat It has a name and a temperature and Yeah, so we're gonna inspect the model in a second Yeah So up there Yeah, we have our table our fields and we're gonna set the temperature to default zero and we're gonna remove the Validation of the requirement for the temperature Just so we have a nice project to work with next. We're gonna look at the database abstraction This is basically holding all your database functions your listeners get her Create update functions everything that you need to interact with the database And now we're basically adding the Crot generated Ui for the thermostats and to our router and this is a basic router that comes with with the project Pipelines are basically what what you want to do on, you know Set accepting coding headers and stuff like that and fetch sessions stuff like that now we're adding the routes for the index page and the show page and starting up the Web server I think no, well, we're migrating the database first of course because otherwise there's nothing to show All right Also, we have tests for everything that we generate so all the getters setters everything that you just saw in the database abstraction gets Generated tests by default So you have something to go off and yeah, you don't have to write everything ourselves Yeah Running the test suite extra comes with different or well Phoenix and comes with different environments So we have the development environment the test environment and the production environment Each of these could or can't have different dependencies So it has different builds for all these environments. That's why it's recompiling again for the test environment Should be done in a second All right, so all of our tests have passed it already has 17 tests that we have automatically generated so now we're going to start the server and Look at the thermostat crude that will be the stuff that we just generated Gonna create a new thermostat named mch 2022 and it has a standard, you know edit forms delete and Also show stuff that you know comes with normal crude operations And what we are gonna do now is basically just tweak that template that we're seeing on the right and we gotta add a couple of things to it to Make you see why we're here first we're committing the project because at the end I'm gonna show you a little nice gimmick about testing and Yeah All right We're now editing basically the template that we're seeing on the right and what we're about to do is basically just add a little Element around the temperature so we can later test on it a little bit easier So basically I'm just adding in a span with an ID term pressure around it so I can reference it later directly Now I'm just adding two buttons that we need to increase and decrease the temperature The good thing about it is the ID attribute is not really needed for the function of it It's just needed so later when we're writing a test for it that we can reference that button more easily So we just copy the button to just make the decrease function as well And our buttons are showing great And now we're just you know adding the business logic behind those buttons this is a fairly standard elixir controller and basically at the top you have the alias for our context for our database context and Now we're adding that we are well, basically we're getting the thermostat that has been passed as an ID and Then we're checking if the socket or the web browser that's connected is connected through a life socket or at least you know web socket or HX fallback and then we're doing a pop-up subscribe to a topic which is a thermostat and the ID That's about it for for that part Next week next we're going to implement the the actual handling of the button. So a function called handle event and the Decrement that we have specified on the phx click attribute of the button we added before next altering the temperature And then calling the update function that we're about to implement in a second Copy that part over all right so now we have a function for incrementing decrementing and Now we just need our update function that doesn't come out of nowhere. So You could technically in case you're wondering do pattern matching on function arguments would look look something like, you know, you're specifying with a Percent sign and then your your class or the object you're trying to to use Would look something like that in case you're wondering I did a coding error there during the recording of the screencast So yeah, I had to use that creatively Yeah, so basically we know having our right function with first argument being the socket the second one being the temperature and thermostat now Getting updated in the database with the temperature that we are passing in and Last but not least and we're gonna send it through pub sub because you know when we're updating We actually want the other clients that are watching that page to get the updated version And so we are broadcasting to our pub sub in the topic for thermostat With the ID and then we send a custom payload which is a tuple of updated which is an atom and Our updated thermostat I think yeah, now we're basically just assigning the updated thermostat to our web page and That's actually all the magic that's required to update Anything in Phoenix life you so you update just the variables that you want to update and Phoenix takes care of this So last but not least we need a function that actually handles the pub sub broadcast or receives it so we're gonna pattern match here on our tuple which is updated and the thermostat Last argument is the socket and we're basically just doing the same as we did in the function before And just when that even happens update variable thermostat in our web page That's all it takes and now we're gonna try it out. Oops. There's a warning so elixir and The current versions tells you that you have unused variables in this case I left it in by you know to show off that you already Learned stuff or find out stuff by just compiling your code within your compilers and Yeah, now we start the server and we click plus and you know updates database to the left You see the orange lines that do the actual changes in the database or debug them Now we are just opening a second browser and see that this is not just Some goofy so you see on the left on the right the the temperature goes up and down That's pretty much as live as it gets Anyone noticed we haven't written any JavaScript yet So those not all so for the last part of this I'm gonna write a test to actually test the functionality. We just implemented so we can make sure that this always works Which is actually pretty nice in terms of You can deliver source code that is thoroughly tested So these are all the functions or the tests for the functions that we just previously witnessed in the crud UI all the listing indexes editing all that stuff and now we're adding a test basically just for Incrementing or increasing decreasing the thermostat temperature Just stealing a couple of lines there so Basically what we're doing is now we're asserting that the standard temperature that is shown on that web page is 42 degrees, which is the default value from our fixture Next we are actually triggering or clicking the increase button And that's why I did the ID so I can just easily reference that button here use the render click function and Yeah, test at the end if it's 43 now copy that test over and Basically write a test for the decrease function should be 42 then and I Think we're done with the test suite Well, all our tests are passing. So we wrote something that works and that's manageable Testable and reproducible last but not least. I want to share a little well what's secret but some fun Interesting in that regard. We're now going to add get hooks into our Mix configuration, which is basically going to ensure that on every commit It's gonna run series of commands And if any of those commands are failing then the commit won't happen So you're gonna have to debug or you know do some stuff in order to get the commit through We are actually doing here is setting a pre-commit hook To do two things One of the things is we're checking if all the code is formatted so mix comes with a format checker There's a configuration file. You can change all the code styling things you want to change And ensure code quality so and at the end it's basically taking care of that So the first command is that in the tasks that we're running is mixed test minus minus check Minus formatted and the second one is just going to be a mixed test command to run our test suite before of course every commit You could set whatever commit hook if you want, you know pre-push or whatever there is you can just do that there now we are Getting the dependency that we just added added Jesus install the hook and We're off to commit our changes Which will fail? Because we didn't format our code. So now let's format it we run that command again and suddenly everything will be committing to kid But it's not all unicorns and rainbows So there are some drawdowns with late elixir and an Erlang so The garbage collection isn't as How do you say it? efficient as other languages, so Be careful what you put into the garbage bin as well I'm gonna say well, actually The best example is if you're updating something a counter on a web page and you're hammering at higher rates a structure with 30 fields through the pops up and While you're just interested in one integer then you know Use a tuple or something that will be more efficient than you know hitting on the garbage collector Another thing is Erlang variables are immutable I mean given in In other languages, I've known the concept, but it can be really hard to to get back to that In elixir happily you can reassign variables. So your structures are all immutable, but you can reassign variables The whole thing has Well, this is not actually a bad thing, but it's a learning curve You have to let learn to enum reduce or in a map efficiently if you're using it, but it's not that bad So the last example is gonna be or for the live coding part adding a risk controller In under 30 lines of code Life updating the template that we just saw in the browser and we're doing it with curl So you could do it from an Arduino or you know, whatever you want to have there just a simple HTTP client is enough and Thing will show off pattern matching with HTTP requests Now we're going back into our router adding or well uncommenting the API endpoint and we're going to add a route for Get request on slash API sleth slash thermostat slash ID and then the call either increase or decrease Now we're writing a new well controller for for elixir. This is basically the other half to live view This is basically a standard controller, which Phoenix supports without problems So you can if you use to MVC or anything like that and you can just use that model But it won't have all the goodies that life you does So now we're basically just writing the basic controller and the function thermostat that we specified in our router The first parameter is the ID address at the ID, sorry And the second one is going to be a call If you look closely you can see the second parameter of the call parameter is actually not Matching to a variable but to a specific string so you can mix and match basically So if you want one parameter, but the other one has to be something specific you can actually pattern match on that So what we're doing now is basically It's the same thing we did before on the life view side. It's basically getting the thermostat out of the database Increasing the temperature and calling an update function onto that thermostat Copy that over make it, you know the opposite function of it and now we have the decrement function Last but not least the update thermostat function, which is also almost the same as before Updating the database So we call measurements not update thermostat first parameter thermostat second the part of the fields you want to change and Once that comes back you just you know broadcast it on the PubSub As we did before on our thermostat ID topic Payload is the same as before Atom of updated and the thermostat we got back from the database and That's about it. So let's try that out. So we're curling the endpoint for You know decrement decrement increment increment and it's you know life updating the the website and we're doing that with curl and No dodgy refresh or anything So the last thing is we are also going to write a test for this functionality Just to show off that it's also not much more complicated than it was with the life view So basically defining our rest controller module aliasing our database context of measurements and Importing the fixture functions that we generated automatically while the just the tests were generated Now we write the test for a slash get the the test for get a slash API thermostat ID and either increment and decrement We get passed into our tests a connection which you can then you know if you work with the tests read a bit more You can do a lot of things there So the first assertion in terms of testing is going to be if the temperature is again 42, which is default temperature Now we're going to test the increment of the temperature. So Get for a slash API thermostat the variable for the thermostat ID and increment we assert that we got a 200 HGP response and Then we are getting that thermostat from the database freshly so we can test if the Temperature went up copy that over for the decrement function and just you know swap the corresponding values So the URL for decrementing is the correct one and testing for the 42 temperature That's about it so Now we run our test suite Actually, we're committing so that's the same thing Now it's the same same thing So our formatting test went through testing the code went through everything is fine So we've implemented all of the things we want to implement in really a short amount of time and We tested all of them So, you know you can deliver products or at least you know you have code that works and not just you know You test it at once after you coded it and stuff like that If you want to learn more about Phoenix or the framework or elixir lang The URLs are pretty easy elixir dash lang org is for the language itself Phoenix framework org is the URL for the web framework itself Hex PM is like, you know elixir's package manager So like gem for ruby so you can look go there and look for you know libraries that you want to use it in your software and There's also hex docs dot PM, which is basically for every package That gets published on hex PM There is documentation automatically generated publish everything they're right for you to consume So Thanks for listening. I hope something stuck find me on Twitter if you want to look at the code again because you couldn't read it on the screen them check out my github and Visit us at the 22 2342 village right next to the hack center. We have Franconian beer if anyone is interested and we're not Trying to take anything of it home with us So if we could get some support in clearing that out, that would be great All right The Q&A will be on that exit outside of that wait. We have plenty of time you have Presentation so much that we can actually do Q&A right now and right awesome Then let's do it. Which is great because this will result that the Q&A is also on the stream and that's great That's great. So if you have any questions, please come to these microphones in here and please Ask away Signal Angel do we have something from the internet? Thank you Seems like me Yeah, I learned something get closer. Yes learn something on you The my constructive critic is the rushing through the code was a little bit too fast to See the details and I would have needed some yes syntax ideas what Interpunctions mean so I can follow a little bit more But definitely worth to look into it So well the idea wasn't to actually teach your language. It was to show you how efficient that framework is so you Actually just wanted to tease you to either you're interested in the efficiency then learn the language and the concepts or you know If that's nothing for you then don't look further But it's also hard to stuff so many information You know if I would have just added one more module or show off then you know It's hard to time then See thank you We do have two microphones that you may line up behind them and I would then Call you out one after the other please go ahead Yeah question How hard would it be to integrate user management and probably even single sign-on with Microsoft AD? Thank you for this great question. That's absolutely not not an issue. There are a couple of open ID connect connectors or Packages that you can use They're pretty easy to implement and the basically you're just implementing about like let's say 30 lines of actual code for the redirect Once you know you come back from the single sign-on so actually just Implementing the parts that matter in those regards and that reinventing the wheel of how single sign-on works So you're probably done in about one or two hours if you're the first time user if you're seasoned one Then let's say 15 minutes Then you have single sign-on user management Depends if you want single sign-on then you don't need Technical big user management in there if you want to implement it yourself Use a crutch generator and add the functionality around it. Let's say an hour or two Yeah So not very hard to summarize very hard. No, very good. Thank you for the question. Please continue. Thank you for your presentation very inspiring But I was wondering can I also write my business logic in Ireland and you probably can Did it I mean Thank you. Thank you I was wondering what the update cycle is looking for the Can you please get closer to the microphone? Yeah, the update cycle for live you and the Phoenix framework like if there's a new version How much pain would it be to implement that? I haven't had much pain in so they're pretty good with backwards compatibility So but if you're using something of the new features then of course you will have to adapt code But I haven't come across that much that changed in terms of if you're using the NBC part Everything stayed the same for you know the couple past couple of years. So That didn't change much life you is the concept. I just talked about is like two years old now I got started when you know version 0.2 point one was out so pretty early or something like that really really early And I liked it that much but you know if you want to port over code Then you know you're gonna have to port over some code to match the new requirements But in terms of backwards compatibility I don't think you have to worry about that your code won't run in a year or two in terms of just because you're updating Thank you awesome just to let you know we have still about 15 minutes left in the regular slot So I would think as opposed to the way we usually do it. We can allow extended questions. Awesome Hey, thanks for the presentation I was just wondering is there any cool tools that you would advise for in your editor? I see use Vim for both elixir and Phoenix framework I mean, I've been a Vim user for you know since I'm 12 years old, so Sometimes if yeah, I've heard people have good experiences with the VS code No, but I mean any tooling that you use in Vim like any plugins that you would advise for Phoenix framework or elixir There's just a plug-in. I think I'm using it with I don't know I configured it two years ago. It just works Wasn't much magic to it. So there's just like a Vim plug-in and use that has everything you need. Yeah, it's also specific for Phoenix. Yeah No, it's it's elixir. Okay. All right. Thanks Thanks, awesome. Next one. Please go ahead. I thought I could ask only one question No, if you if you like to keep more distance between you you may also use the other microphone in the back I will equally switch between them. I Was wondering what is the underlying database that was possible is girl, which is the default for all Phoenix projects So but when you're generating the new project I think you can just specify which database rather you want to use and then everything gets generated for most of the common databases CQ light my Cql. Whatever you have there not in Asia I haven't specifically looked Because that's another secret. That's the the air long built-in kind of database. Yeah, but we're basically using Ecto or Phoenix is actually using the Ecto Cql object relational management system. So I don't think it comes with amnesia support I could be wrong. I haven't checked but I mean people have implemented other key value source and stuff like that as You know an adapter for for Ecto. So I wouldn't be surprised if there's really an adapter for so Thank you right Hello again, hello again, how big is the code that gets sent to the client the initial Libraries that gets loaded. They're actually pretty small if you're not, you know You can work with the JavaScript part of it. You can inject your own stuff. No problem at all So it gets bigger of course, but the standard stuff is rather small I haven't I couldn't tell you off the top of my head But it's it loads and seconds and there's no bloat in it. So it's really just the underlying Life view JavaScript and a couple of other. I think the top bar thing so you see when the web page is actually reloading and stuff like that, but To my knowledge that's pretty insignificant in terms Of loading size like like 200 kilobytes, maybe or is that probably less even yeah, I wouldn't be surprised good Thank you, 30. Okay Thanks Thank you. All right, please the back microphone now Sounds about small Hello again Are there any other web controls or bootstraps you can include and How do you work on the JavaScript part? There's an app.js file in the project. You can just you know go ahead and work with that But you don't need to that's the whole thing of the talk Doesn't mean you can't or you shouldn't but you don't have to if you don't want to so Yeah, and using any other web controls, I mean like telleric Yeah tailwind is easily available as a gem as a hex package so you can just you know reference it There's a pretty awesome tutorial on it You have just just Google for it for Phoenix framework tailwind And you will step on it. That's probably the first hit on Google. It's very good. So the front microphone, please You used pups up. Do you recommend it for large projects? I heard that it can be too limiting other order messaging ways To is it included? Yeah, it's basically it comes with the distributed pops up the thing I like about it if you're using the pop-up stuff You can just cluster or scale up your installation show So whatever your project may be and you need more instances or whatever you can just cluster and that the pop-up stuff Basically, you know takes care of you know I need to reach all of the nodes because you're basically having just a big pop-up cluster So, I mean if you start a really a lot of messages going on are there alternatives to pub shop or do you not recommend that? Haven't seen a single person actually doing any alternatives to it I wouldn't advise using an alternative, but you you have free to try Okay, thanks Thank you Do we have a question from the internet in the meantime signal angel that is not the case in this case? I would like you to give a round of loud applause for France Thanks