 My name is Vina. I work at the SPD Digital as a software engineer. Tonight I would like to share with you more like walkthrough with the live demo with all of you. This is one of the famous web surface sites called Fever. But specifically on Fever Fashion 3, why? Because I think it's so cool. Can I like know how many of you have heard Fever before? Wow, okay. Quite a lot. So some of you might have asked why Fever, right? I have this graph that is presented by Tanner Nelson, the creator of Fever himself. He actually presented this in TriSwift conference in New York in 2017. His argument is that as a Swift developer, you probably want to build on app and you need a backend. So you have a choice like CloudKit, Game Center API, or Firebase as a backend as a surface. On the other hand, in terms of the functionality, you can use very advanced stuff from ExpressJS or Ruby on Rails that can do almost everything. But the learning steep for you is very high because you have to learn a different set of skills all together. So that's where IBM, Qtura, or Fever comes in whereby you will still get to use Swift but you can still build the same functionality as those traditional frameworks like Ruby on Rails or Node.js. So I highly recommend you to read the post about his talk here. Alright, so next I'm not gonna waste another time. We will jump right into the setup so I hope you can follow it through with me. The first thing that you need to do is that you need a Swift 4.1 and for Fever, they actually provide a very convenient check which is this command line. And when you hit it, they will actually tell whether your system is compatible or not with the Fever 3. If you have difficulties in setting up the Swift 4.1 in the command line, you can use this Swift ENV in which I'm also using it right now. If you have it installed, you can choose what is the global Swift version that you want to choose. I find that the command line and the Xcode are two different things, meaning if you are using Xcode 9.1 or 9.2 like me, chances are you are still running on Swift 4.0 and it cannot run, it cannot do Fever. I'm gonna need to switch back. And chances are you need the Swift 4.1 toolchain to run the Fever. For example, once you launch your Xcode, you can go to the preference under the components and if you have the toolchain installed, you will see the Swift 4.1 release being used. And nevertheless, once you install this, it doesn't mean that your command line will run on the 4.1. You need the Swift ENV again to set it. So once you have this set up, you can use the Fever tool box to kickstart your Fever version. For example, I already installed using this brew install Fever and you can also do brew upgrade Fever whenever you want. The current one is version 3.1.4 and this is how you generate a new project Fever, new for example also API dash dash branch equal to beta. And then you see it with that folder. Oops, sorry, I get ahead of myself. So for example, I already inside the project folder. It's because before this, I was trying like after I do the Fever new, I actually execute this thing called Fever Xcode dash Y to generate the Xcode project file. And it takes some time to generate or fetching the dependencies that Fever needs. But once you get it, they will actually open the Xcode for you and you are able to run it. What you need to do is that when you open it, usually the default target is this package. So all you need to do is just change it to run and click run. And it should run the server. As you can see here, it's actually running on localhost 8080. In that case, why is it not found? I'm going to explain it soon. I can't speak this. Why is it not found? That is because we're going to jump into the next topic that is about the routes and the parameters. The routes basically explain that the URL that you want to hit or usually we call it the endpoint. You can see in this file for routes.swift, there's the router.getHello and just returning a simple string called hello world. This is exactly what I just need to append it with slash hello. And then I'm going to see the hello world here. So everything that you define in the routes.swift actually will be reflected on the user side. Now, if you want to add more parameters or let's say you want to capture more parameters, I already prepared the shortcut. I'm going to capture a hello slash somebody as a string. And then what you need to do is just adding one more router and then you capture the string, convert it as a parameter, then return it to the user. I should say this. If I run this, I should be able to capture, let's say, for example, hello Stephanie. You see, the beautiful part of using Swift is that you know that if the parameter is a string, you can still use the string function from Swift. So you don't really need to find out like, oh, I want to use Ruby on Rails. How do I process string in Ruby or in JavaScript? And let's say if I put a breakpoint here and I capture again, I reload again. It's actually stopping at the breakpoint. So it's really nice to use export as an IDE because we are so used to it on a daily basis. We always use export for and we can continue again. You can even inspect the memory that they're using. I mean, isn't it cool, right? All right. The next question will be like, what about if you want to capture more parameters? What I mean by more parameters is that, for example, I want to capture three parameters, string, if, and string. The conclusion is that the extraction order matters. What do I mean by that? Is that with this code? If I have three parameters that I want to capture, string in string, but when I capture it as string string int, it will throw me an error. Wait, what happened here? Oh, the next. To get rid of the next. If I rerun it again, let's say I'm capturing two parameters, one is string and int. I can go to Halos Stephanie's last, like, 21. And I'm capturing it properly, right? But if I edit some more with, let's say I want to eat, it's going to return me an error saying that invalid parameters like string int. This is because the extraction order matters should be string int string rather than string int. If I switch this and rerun it again, I should be able to get it like that. So that's pretty much about routes and parameters. Any questions so far? If you want to ask a question, please feel free to ask any, stop me anytime. The next is how about returning a JSON? We definitely need to know how to return a JSON form of an API, right? To return a JSON is very simple. You just need to create an object as a model which is instruct and create your route. Let's go to the example right now. For example, I'm going to create a struct called topContentData, which has a title, type, sequence, start time, and you just need to generate the route. The route basically is saying that if you hit slash top, I'm going to create a top object and return it to me. Every time you do this, you have to reload again. Reload again and this time I have to say slash top and it's just really simple as simple as that. That is how you can return a JSON. The next thing is I'm going to need to touch on the Faber-3 asynchronous architecture. Why? Because it's one of the biggest changes since Faber-2 and Faber-3 because when Faber-3 has asynchronous architecture, they got a lot of performance boosts and they built it on top of Apple Swift Neo, the networking library. To make use of that, you simply need to wrap your request in promise and that means that, for example, if you used to return an array of top, right now you just need to wrap it in a future generic array of top. Just like that, yeah. And then a simple tips on how you work with the futures, which I got from Ray Wendelik's Faber-3 book chapter 4 that you use flat map when you want to return a future. You use Mac when you want to return type other than future. You use transform when you know the future is going to be completed but you will ignore the result. For example, when you delete an object, you simply delete it and not returning the same object to the user. You just say transform to STP status okay to give 200 status, saying that oh, I already delete it. Yeah, just like that. And then, data persistence. I should show you first how Faber handled this by default. You can see in the configured of Swift, right, by default when you kickstart a new Faber project, they use SQLite. And they're just saying, if you don't have a SQLite underscore path in your environment variable, they're going to start it in the memory. Well, that means that anything that we post to the API will just be lost, right? So we have to find a way to process it. Now, one of the beautiful things about Faithport is that they have the Fluent ORM that supports SQLite, MySQL and PostgreSQL. I think there are more. I could be wrong. But let's say for simplicity of this demo, I'm just going to use SQLite and so I can delete this and replace it with SQLite path that I want called db.sqlite. Okay, so right now I don't have any db.sqlite and once I run this, it's going to create the db.sqlite for me. So right now we are ready to sort of make the creation persisted somewhere in the database. However, just for a suggestion from the creator of Faithport itself, do not use SQLite in the production. I'm not sure whether that's agreeable or not. Yeah. So without further ado, I'm going to demonstrate to you how do we do the crowd demo, the create, update and delete. First, what you need to do is you need to create a top model, just like how we did with the parameter disk now. And you also need to create a file called talks controller to handle all the get and post method. One thing for me is that you need to generate the sweep file from the terminal so that you get the right file target. What I mean by file target is that you know, in this, every sweep file they are attached to one target membership here. So by creating it from the command line this will help you to get the oops, sorry, get the right target. Sources, app, models, sweep, sources. So after you create this, you typically need to do another paper code. The reason is because it's not instantly show or updated here. So this is the reason why you have to regenerate the export approach again. And they should, okay, I should stop it. Generating one-to-one. So they just gonna do a load and now you see your file here. Talk controller and top. Okay, now we're going to do the talk model. Luckily I already prepared some good stuff. Now when you create a top it should be you should import the paper you should also import the flow in SQLite. There are other if you are using MySQL they actually have my SQLite. I don't know, the auto-complete is not working here but it should be. I think should be like that. Yeah. I think this is correct. See we got a line. I don't support PostgreSQL. You already. All right, anyway. It should be a subclass of a codeable where you can define your ID and you should create a constructor for that. And you should subclass from SQLite model migration, content and parameter. That's by default. Actually the explanation is that migration is for the database content is when you want to create a top they will need to map it to content and then when you want to do like get one top by ID they will need to do the parameter. And then for the edit to migration section in configure, oh yeah in the configure they actually have a migration here. You just add your model there so it will be top. So and then next is the top controller. Top controller will be okay by default a top controller struct is needs to conform to protocol route collection that you only need to implement one function called boot. The boot will have something like red route the author.group I want to say to access the api you need to use something like slash api slash tops. And then you register all the handler here. For example, I'm going to register for get all handler. It's the same thing with I want to get all the top. And then after that you register it to get. If it is a get use get all handler as simply as that. And then how do the routes function know that you actually have that controller is that you have to register it in the routes.swift so the routes.swift we will know that oh I have this router registration from this task controller so now if we run this and I'm going to use RESTed to test it so this REST is going to do an api call to my local host and I am actually getting a 200 okay but it's an empty array why because we don't have any talk yet right nevertheless we already have the basic get so next is there oh sorry I still need to create I still need to create the create handler to create handler here so the create handler basically says that I need I'm going to need to pass a JSON body from this talk create data did I create a talk create data so this is basically saying that I'm going to pass you a JSON that should matches this talk create data and after that you create the top object and then save it in the database I guess we have to try oops sorry register the route here so I need to add the create handler the route should be a post and if the post has a parameter okay notice that there is a lot of Xcode annoying stuff like this which I'm going to talk on later create handler this looks to be okay so now I get all talks and I still get empty array and I'm going to create a new talk for example this is the talk that I'm creating and I'm actually getting a response body which the talk that I created and it's actually automatically assigned with ID number 1 so we can do another one favorite number 3 is awesome yep I'm getting ID number 2 now and then for example this one is once create and then send request again and I'm getting an ID number 3 if I go back to the get all talk I should be getting all 3 awesome right so just by like how many minutes pass already almost run 15-10 minutes you basically already have your own local host API running now just to get everything quick right we're gonna need to add like 3 more one is the add get handler get handler means like you get one talk based on the ID again you do it in the talks controller get handler if you are if you are getting one one talk by the ID you can still use the future but you don't really need to use like flat map or anything it's just that you try to get the parameter itself which is the talk and then for the update handler we'll just add the update handler first update handler here the update basically will try to parse your talk ID and then say that since you're posting a new data of that same talk it's just gonna do the you know the plain old like the old one equal to the new one okay and then for the delete handler as the example mentioned before what you need to do is just like you search by the top ID and then you do the talk.delete and transform to you need to tell me whether it's okay or deleted or not right so after all this remember always remember to register your route here for example just now the the update is still using this one right talk.parameter using update handler except for the delete there's another special delete but you still have to capture it using this talk.parameter actually right when you create the object and you subclass it from the parameter if I command this it should throw me an error right it's because when you subclass it to the parameter oh sorry when you want to post you need to subclass it from the parameters yeah like that I think we can run it now so what we need to do now is first remember that we implemented the one get talk by ID so we had three talks and then let's say I want to get the top ID number 2 what I need to do is just get it wait what did I run it oh yeah okay this error actually really told you that there are two routes two that has the same route because I register here as a talks and did I also do the talks here yeah I think I should command it first oh sorry sorry this one has to be the different so if I want to get top by ID number 2 wait yeah update handler overriding route output at post api talks if I go to the api talks I still get all three open the id one two three any idea I haven't created it yet good one if I talk the parameter then I should use get handler nice one thanks for saving me yeah so if you want to try to get talks that don't have the id yet it's gonna just by default throw an error and then the same thing for update handler if you want to update top by ID let's say I want to update top number 2 to be this title so I'm just gonna post it and get the new one reassign the new one and you get the all talk again and it's already changed to the one that I'm changing the question here is that can you change the id can I change the id if I try to change the id let's say I want the id to be now is number 5 and I send request it's still returning me the id number 2 so the answer is no you cannot change the id you are deleting you also need the id let's say I'm deleting id number I'm gonna get id number 2 it's giving me okay that means I assume that it's deleted already right then we go back to get all top what happened the id id number 2 is skip id number 2 is skip and the same thing if you try to delete id that is not exist it's just gonna give you error so this is really like the nice thing about the fluent ORM that comes built in with paper right so yeah in conclusion right as a swift developer who is using in and they out I really think that to be able to use xcode and switch to build server side api is really nice and I'm just like liking it you know I can I don't need to learn a lot of new things the only thing is that I just feel like it's very swiftly yeah it's very swiftly I still think that there's a lot of things that I'm like about this paper in times to come but there are also things that I feel like meh you know whenever paper there's a paper update the thing that makes me scared is it's actually breaks the existing code for example like just like two days ago I was still creating this thing and I'm still following the old one like request parameter but as of like I think this afternoon suddenly they give me all this funny funny like warning and said oh I should use parameters next now and I don't really know what it before and so I just like okay just try to fix it so you have to be prepared of these sudden changes and then Xcode still lacks of autocomplete like it's not how you saw I was trying to search for fluid my my skill like my skill and this kind of thing they still lack of autocomplete and then too many training may crash your Xcode like for example when you try to do a lot of flat map and then dot map and then you want to flat map it again it can actually crash Xcode and the last thing is that when you trust your database performance or migration to paper fluid that also means that you don't know about the database performance that they're actually how they're doing how they're indexing and stuff like that yeah but I believe that vapor team will improve all this tiny little bit things that we have concern about yeah so just the last slide I'm just gonna share you some of the resources that I think will be useful for you especially probably from this is the slack group they're highly highly active even the vapor creator himself is actually actively answering questions there because as you know the documentation for 3.0 is really not accurate yet even as you speak right now there are so many tutorials up there and they are not really um they're not really accurate yeah but this is the very reason that I want to share with a live demo so that you can uh really see that actually it's it can run and when you want to get started you can always re-watch this video again probably like better guarantee to run yeah I guess that's all back to step Vina for sharing what's about vapor questions for Vina oh okay yeah definitely definitely can so you can get a yes they use a live templating engine okay anyone else alright if you have any questions for Vina you can ask her later after