About this talk
Having a strong data layer, Ember is well suited for the task of data entry, it allows for easily building data encoding tools, complex forms with foreign key dropdowns, several levels of nested records, translations and more. But building such a tool still requires lots of boilerplate work mainly synchronizing information like API definition and "possible actions" between backend and frontend. But it doesn't have to be that way!
So SDK for the web, Ambitious application. That's things we hear a lot about Ember and I so I thought, what about a rapid application involvement tool for the web? Does that sound ambitious enough? Does itwith SDK, I think I does. So before we get started. Who am I? My name is Emma. I work for LevIT which is a small company in Belgium that I founded. I've been working mostly for the web, over 10 years now and I started looking at Ember like four years ago and this is my first Ember conference, so I'm a bit nervous to be here in front of you and present stuff, but I hope it's going to be okay. Just for a fun story, in some non-Ember conferences, I'm starting to be known as the Ember lady, because I'm trying to sell Ember to everyone and I can not just stop talking about Ember. Yeah, I forgot that one. Okay, so a long time ago, in web years it was about the middle ages that was like 15 years ago, I use to work on the LevIT applications like that. So the screen shots might be a bit small, but those are a lot of forms and lists of data and those screen shots are actually from two different applications that are quite similar because one is the fork of the other one and the first one defines itself as a NRP and CRM solution and the other one defines itself as an application development frame work. I will just say that those are nice tools to build instant forms for a lot of different models and a lot more because this application usually will be between tens or hundreds of different models, like for example all your products, all of your clients, orders, invoices, everything and it soon adds up. Before we go any further, I have to make a confession, my back-end frame work of choice is Django. And I'm pretty sure I'm probably the only one in this room who using mainly Django. So I'm going to do, hey hi, I'm going to do a quick survey to get an idea here. So please if the main back-end that you use with your application is Rails, please raise your hand. Okay so that 2/3 of the room. Now who's using mostly Phenix as a back-end? Okay that's two, okay. Anyone using PHP? Okay, quite a few, more than Phenix actually. Byton is only you or two, three, four, five, whoa. That's not that bad and is anybody using no back-end, as in server-less? Nobody using it, yeah one, okay. Good. So, I wondered, you know those applications that I just showed, those screen shots? What would it take to build such aof application with like the technology like Ember? The usual way to go about it is that first I would go to my back-end, and define some data structure either in the data base or in the ORM, and then I would have to duplicate that effort and create some serializers that are basically not always 100% the same as a table that they areto, but they're like 90% the same and then I would have to do that a third time and I would have to create my Ember model, which is exactly like my serializer and once this is done I would have to actually create the form and set up everything so that it looks nice, but yeah that's the way that we usually do things, but I'm lazy and I don't want to do all that. I don't want to do the same job three times. And so I wonder, do we really have to, because when we look at this, so this is PHP, I know that there were some people who are going to be doing some PHP so I decided toas PHP. So when you look at this, on the right you've got doctrine PHP model definition and you've got like a lot of fields, you've got ID, which we don't have in Ember because this is automatic, but we've got a name, sale type, the price, description and basically we have the same information in our Ember model. So could we say, you my back-end, you know about this, could you please give me the model directly? And while you're at it, I see some people squinting, don't squint, this is ES5 and this is the same model definition as you saw before just it's ES5, so this means you can load it directly in any browser that is supported by the 2. X French of Ember and so if my back-end was able to produce that, I could on the fly, say okay go get that JS file that represents my serializer and use that as model. Well actually, you can do it. This is the code to do it. So this will load the script as a script and then it will use Ember registry to actually load it and define it as a model that can be used in Ember and this will work, if you buy that this will work, until you try to create a product because then it will crash and would say, hey I don't know anything about category, you don't have any category model so I can create a product, but other than that, this piece of code is three lines of code will allow you to load any model. But we're still losing some data. Even if we're able to load that JF that I just showed, we're still losing some data from the back-end, the back-end knows a lot more about your model than Ember at this point, for example, this is Django, I'm going back to Django, I did one speech, but now I'm going back to Byton. So here in this model, you can see there are things different with choice field where we see that actually the cell type can be product or service and product is going to be P and S for service. We see that we have a decimal field. In Ember we just have a number field so I could be floating, we don't know. We have an image field, in Ember its just a string, its the URL of the image, but there's some information there. We have a text field which is different from a string field because it's just larger, we know its going to be, for example, exterior. And we have some fields that are required. The last two can be null. L equal true. So they're not required fields and words missing that are also in Ember, we have fields, but we don't know which one's are required or not. And so it would be nice to be able to call the back-end and say, hey tell me absolutely everything you know about this hand-point so that I can be more meaningful and I can create some stuff and have more information about it. Actually, there's already something that helps us with that, it's called options. Well you can get but post, delete, but you can also go the options route and we all do it all the time and we call the options route and it tells us, alright what are the yellowed methods and yellowed headers and what counting type is expected and all those things, but it can also give you adjacent content. So, since you're back-end already knows about that and basically your back-end is called every time you call an endpoint. Could we have all that information produced by the back-end? Well we can. You can see here that something, that's a partial output and this partial output could already be created by a library that I bought Django and this gives a lot more information about our model. We have some label, which is basically just capitalised the name of the field. We have the information if the field isor not. What kind of fidget screen to be using. Is it like a number, an image, referring key, an ID for some fields we have some extra information like the name of the related model or the options for a select box. It also solves the problem that I mentioned before if feel like that last thing needs, it needs to load another model. Fredrick needs to load category or it will not be usable. And so since I wrote a back-end library for it, of course I needed a front-end library to use it. And so... yeah... Why is it not working? Okay and so there's a library for it. Its called Ember-cli-dynamic-model, don't ask me why I said cli, it just sounded cool at the time and then I realised it has nothing to do with cli, but now the name is there so it's Ember-cli-dynamic-model and it exposed surveys that allows you to ensure that the model is loaded and if the model is not loaded it's going to call the back-end and get the model for you, do the option call, make sure that all the other models are loaded and it will let you use this model and once you're sure that the model is loaded, so I'm going to try to highlight that. So once you're sure that the model is loaded, you can actually go to the store and get the model you wanted to get. And so this is a service so you can check components, invoice, whenever you need it. So of course, I've got a back-end library, I've got a front-end library and I'm sure you want to see it working together and so I'm hoping that this kitten, this is only the second time that we see kittens in this conference, I'm not use to that, I'm use to seeing a lot of kittens, here's a nice kitten and it's programming and it's using Ember. And so yeah here, I need an example so I decided I wanted to sell some Tomsters and so we have some Tomster products and if I fill out this page and please open the inspector, okay. Network. I'm going to filter on thatfile and I'm going to reload the page. If I reload this, you probably can not read the names. It's not that important, but here you will be able to guess that this is product So it's loading dynamically the products model. It's also loading the category model, it's too small for me to see, but it's also loading the category model and it's also loading all the data that it needs. So I knew I had forgotten to open one tab. So for example, if I go to product. I'm going to zoom in so that everybody can read. Okay, so I've got here my product end-point and if I call the options route on that end-point, I get some information, I get this needs that I was telling you about. It's telling me that it needs the category model that is part of the application products and it's giving me a lot of information, including field sets and things that we're not going to look into right now, but you see here you've got the list of fields. All the fields that are used. This almost the same that I showed you before, except this one is live and so you can see that this is actually working. But hey, I have all this information and it sounds like quite a bit of information just to sell Tomsters. I do want to buy Tomsters. I want the new Berlin Tomster, everybody wants one. And I want Tomster to teach me some things, but yeah. There's so much more information that I'm getting from my back-end and what can I do with that? I guess what I can do, is that I can use that to render some lists and some forms. So here are all the models that I used for this website. You can see that there's the products and the categories, but there are also some companies, some invoices, and yeah, something to run a full web shop. If I go to product, for example, here I get my list of products and I can go here and edit my Tomster, my Berlin Tomster andby me. And then I can save that. And yeah, to do that, all I had to do was to take all this information about the field, exactly what kind of field it is, not just a string, but an image field and put that in a form builder and I've looked on the web, to try to find some form builders and I found some for, for angular, for view and for Ember I found, Ember IDX form that works with Ember one and last time I checked, it didn't work with Ember two, so I said, okay well, I'm going to create one so I created Ember's eli credityes which is the library that's used to render the forms. That library is actually not that good and if somebody wants to rewrite one, please feel free, but right now it's the only form builder that I could use on Ember two so I had to do that. But with that I can do a lot of things. My Ember's application is actually quite dumb, it doesn't know anything about any model, it just know where to get the information about the model and from that I can build some lists, some forms. I can do anything crat and I can actually do more than crat. If I go to, for example, my invoices, you can see that for my list of invoices. Here I've got a lot of buttons, I can do more than crat. I can download the pdf for the invoice, I can mark my invoices paid, or I can make it as draught again. I'vea lot of actions, and all of those actions, where did they come from? Well, they are just part of my endpoint is invoices slash one slash pack, invoices slash one slash download. It's just part of my endpoint, and so this information was given to me from the back-end as well. The back-end knows everything. It's where the endpoint live. So the back-end knows that information, and pass this information to me, and with, of course, some sytanx that was defined by me. Some syntax, I'm able to displace on a list of actions. And you're going to say, ey well, you know, this looks like admin. Ruby is an admin, it's got Ruby admin, Livewire is an admin, it'sadmin. Django comes with an admin out of the box. There's even something that's called NG Admin and React Admin. Now it's nothing fancy. Yeah, well, nothing fancy is that there was not really much of an admin for Ember. There's a package called Ember Admin that was done by, I believe, and I don't know if some people from want to say anything about it, but I don't think they are developing it anymore. They stopped, and it didn't go that far. So yeah, there was nothing for Ember, so someone had to step in and do that. I mean, it's not just a regular admin, because Ruby Admin, for example, if I go here, my companies, edit it this, something that's usually not possible to handle in admins is the too many relationships, one too many, thuspossible. And when it's possible, it's only possible one level done. And if you want to go two or three level down, it starts to become tricky. Here, for example, I've got my company, and it's got some employees, I can add an employee, and each employee has one or more contact mechanisms. And this is like a tool ofrelationship, and I can go three, four, five level, as many levels as I want because I'm on the front-end, this is dynamic, and I can do everything I want, and much more easily than on the back-end anyway. And so here, I've got my new employee. And this is something you absolutely cannot do on a back-end, is a, if this was back-end rendered, to be able to say that my default contact is my new employee that I am just creating now, that I haven't saved yet. I would have to do some pretty weird jQuery to be able to do that. But here it is, it's Ember, so it's a data model, it's already created. When I press that plus button, there is a new line in Ember data, and so I can pick this new employee as my employee by default. So enough of saying Tomsters. This is nice, this works for Django; I wrote it, I am happy. What about other backends? Because, like, 2/3 of the room, like 3/4, 2/3 is not using Django or Python. What about the other backends? Well switch to Django. Well, no, I'm just kidding. I actually started writing something for Phoenix, which is quite difficult because Phoenix is like a functional framework, it works in a functional language, so it's totally different approach. So I wanted to start writing that to see if it was possible. And I also started writing this for AWS with lambdas, because, well if you're using Ruby or Django or whatever, you still can already get something pretty decent with regular admins. But what if you're using AWS and DynamoDB? You have nothing. You have some interface where you can type some, but it's pretty limited, you cannot do much. So if you could have something that runs on AWS and come and plug your Android application to administrate your database, that would be create. I will likely also do Rails and Laravel if I've enough availability, or if some company decides that they want me to do it and decide to pay me to do it. So if you want to pay me, please come find me after the talk. And I will probably not do anything about those, because I believe this goes against the ideology of those frameworks. Okay, but remember at the beginning I said that these old applications that are like 15 years, they're able to handle tens or hundreds of models. And like, there were seven models in my demo. But yeah, just for the information, that demo was running on my local host, and I see that here 90% of the people have MacBooks. This is actually a Chromebook. It's got only four gigs of RAM. It's got a CPU that's underclocked so that it's not going to heat up. So this run pretty smoothly on that computer. But yeah, that was still seven models. How am I going to handle this when I have to build an application with 100 models? And when you try to load a model, it kinda flowed the entire tree of model, because this model, the customer model needs the invoice model that needs the invoicemodel that needs the product model. And yeah, you get my drift. So are you going to dynamically load hundreds of models like that? That's not going to work. It's nice in development because once you make a change to your serializer, to your endpoint in the back-end, it will be directly mirrored in the front-end. But in production, you don't want every time that somebody loads your application to load 100 different model files. So I'm going to talk to you about this other application I'm writing. You don't need to be able to read the name of the endpoints, but you see there's about 40 endpoints in here. And all those endpoints, most of them can do , but a lot can do more, like we saw with the invoice, download a PDF, mark something as paid, or something. And for that application in production, instead of loading everything dynamically, I added one step to my deploy script. And before building my front-end, I export statically all the models from the back-end serializers to the front end, I have just have to give the paths of the front-end, and it exports everything as static files to Ember. And then you can build your front-end and have it served with the rest of your app. You can use those models to run tests. I'm pretty sure you can also add some scripts and build some factory-guy scripts to build data, to be able to run your tests. And by exporting those, because right now we've talked about having Ember models reflect exactly the serializers. But it's not always the case. Most of the time in your models, you will have some computed properties, you will have some methods that you want to run on the model. So you cannot just take dynamically everything and say, okay, where does my code, my own code, where does it live? So if you were to export the model the statically, it will export to five. Here you can see all the models that I've exported statically for this application for 40N point. And there's a base directory in there and so the base directory this is where the exported code lives and if you don't have anything yet, it will create also the real model five. For example, here the first one, invoice. It will create it and it will direct it from the base invoice file and so every time I make a change and I want to re-export my models from my back-end, it will override the base file and you can write all your code in the invoice JS tech itfrom the base file. So the base file will have all the fields, for example, all the attributes and links too and everything and the other file will have your computed properties, who matters in everything you need. So I'm going to show you this application as well. If I can get my mouse there. Okay, so here's the application, I'm going to reload it, this is over the wifi, this is not running from my local host. Here I'm loading everything, you can see some stuff from other torques today, like non-blocking rendering and stuff like that. And so we can see here we have nice dash board and everything and all those are not loaded dynamically anymore, they're loaded statically, they've been compiled into your Ember application like any other regular model, except I didn't write any of them. They all were exported from the back-end. And here we can see that we have some pretty nice stuff. Like for example, here it is invoice that my client should pay me, this is all desk data, the names of the companies are real, but the amounts are not real. And so if I click that button, here comes a form and this if a form, this is some data it's going to mark my invoice is paid, or partially paid, depending on the amount that I write. Well this is not a back-end model, this is going to be use on the back-end model, but it's not a back-end model just a form. But on the back-end it still uses a serializer. So I can take the serializer from my back-end and still export a front-end model for that. So remember, this is a model. On my back-end, this is not a model, but there's some data that is going to be processed by your serializer. And so if I choose an account and then click here, pay. My invoice is not paid, you can see that there is zero left to pay and this is all good. And so I see that I am running a little bit late so I will just go over this. I spent a lot of time to do that. This started like a pet project, a bit over a year ago and yeah, I did spend a lot of time on it. And you know the longest time I spent was actually on the form builder, if not on the idea of transferring data to the back-end from the front-end, it's the form builder that took the most time. It's probably the least, production ready codes. All the libraries that I mentioned are still alpha because as I mentioned I want to use the same concept on different back-ends and I might still break some things, but I'm using this in production and actually I'm using this on any new Ember project that I started has more than five models. I don't want to spend some time to keep them in sync with the back-end. I use this for everything. And so it does what it's suppose to do. The first link here is the link to the slides and everything is clickable in the slides. So you can go check the demo, at least the web shop. You can go see all the documentation for the libraries, you canthe libraries and everything. Great. Thank you.