 Hello, my name is Matt Rabel and I am a developer advocate at Okta. If you want to learn more about Okta, what we offer, I invite you to go to developer.okta.com. If you'd like to know more about me, I invite you to go to Twitter, I'm on Twitter at mrable. I'm also on LinkedIn at mrable. I have a website at rabaldesigns.com. And today we're going to be doing a basic CRUD tutorial and building an app with Angular 5 and Spring Boot 2.0. Spring Boot is an opinionated way of building production-ready Spring applications. You can build web applications and APIs very quickly and easily with the Spring platform and Spring Boot. And we'll also be using Angular, which is a very popular framework for building front end applications with TypeScript. Spring Boot 2.0 brings in a pretty significant feature in its new Spring Web Flux framework. However, I'm going to keep things simple and use Spring MVC. Angular 5 has a new HTTP client as well that we will be using. We'll also be using our Angular SDK to build an app that basically allows you to view a list of cars, edit that list of cars, add to it, and shows an animated gift that matches a car name. You'll need Java 8 and Node 8 installed to complete this tutorial. So to begin, we'll start by heading on over to start.spring.io and create a new project that uses Java, Spring Boot 2.0.1, and Maven. So to begin, you will want to type in a group ID, and usually you'll want to use your company name or the reverse domain name. So I'm going to use com.ocda.developer. And then for dependencies, I'm going to use JPA, H2 for a database, Embedded Database, Rest Repositories, Lombok, and Web. I also like to add actuator just because it's a very cool feature of Spring Boot. It allows you to monitor your application. So then click Generate Project. That'll create a demo.zip or whatever your artifact name is. I'm going to create a directory to hold both the client and the server projects. So we'll create that using makedir. And then I'll move the downloaded demo.zip from DownloadsDemo into the server directory of my new parent directory. And then I'll CD into that and open that in IntelliJ. And the first class I'm going to create is a car.java that basically just has an ID and a name. And it'll use Lombok to reduce the boilerplate code. So we just need a bunch of annotations instead of actual getters and setters. So you can actually paste it right in there. And IntelliJ will create the new file for you. And then I'm going to create a JPA repository that allows me to crud with my database, that entity. So Spring Data makes that very easy to do. And then I'm going to create an application runner that populates the database. So this is just a feature of Spring Boot. This application runner will insert a bunch of default data. I'm going to use spaces instead of tabs. Space people make more money according to Stack Overflow. But you'll see we just have a number of default cars that we're going to enter into our database. And then we'll start up our application. And so we can see those cars have actually been inserted into the database. So now we'll create a cool car controller. And this will filter out the cars that aren't so great and just show the ones that are cool to look at. And hopefully we'll get better, giffy images from that. This does a find all streams and filters it. So it filters out the gremlins and the stag and the pinto and the Ugo. We'll have to restart our app for that to take effect. And then we can use HTTPIE to actually talk to that endpoint of cool cars and see that it's filtering out the ones that aren't so great. So that's working. We have Ferrara and Jaguar and Porsche and Lamborghini and Bugatti. And so now we'll create an Angular client using Angular CLI. So Angular CLI is a great tool because it basically allows you to get away from writing a bunch of boilerplate code for your new Angular app. This will install all the dependencies as well. And the first thing is I am going to use Angular Material to make it look a little better. So install those dependencies. The CDK is a component development kit that is required by Angular Material, but it doesn't pull it in by default. And then we're going to use Angular CLI to generate a service called car. So g is short for generate, s is short for service. And then we'll put those in a shared directory. This is just a convention that I like to follow. And then we'll open it up in IntelliJ, which works great for TypeScript. In that car service, we're going to make a call to that cool cars API using HTTP client. And I don't like to compile my TypeScript next to my JavaScript because I have a webpack to do that for me. We'll add HTTP client as a module to our app module. And then we will also specify car service as a provider. You can also do this on the component level, but it's typically easier to do it at the module level. And you'll notice we have some warnings. Our imports look kind of funny. So I'm going to change TypeScript. So it puts some space padding around that import, spaces, and then ES6 import. And then also change the punctuation so it always uses single quotes instead of double quotes. And now if we hit Command Shift O, that'll actually reformat it correctly. And it'll get rid of this white space because I like it nice and concise. Now we'll generate a car list to display those cool cars from our API using ng generate component car list. And this car list will use that car service, call its get all method, subscribe to its results, and set it to a local variable called cars. We'll import that car service. And now you'll need to update the car list component html to show the list of cars. ng4 is how you loop through data in Angular. And so we just display the car name there. And then we're going to update the main page, the app component dot html, to actually render that app car list. So now we'll start our application using ng serve. And this will recompile and refresh if anything changes. So go to localhost 4200. And it doesn't work, but it's because of CORS, C-O-R-S, cross origin resource sharing. So we need to enable that on the service. You can do that with cross origin annotation from Spring Boot. It makes it very easy to do. So we just add that annotation. And we'll also add it to our car repository. So when we're doing CRUD, not just fetching the cool cars, but editing cars, it'll work there as well. So then we'll need to control C and restart our service. And now our application should be rendering those car names. There we are. So we got the cool cars rendering. Let's go ahead and add some Angular material components so it looks better. These are all the ones you'll need for buttons, cards, inputs, lists, and animations. So in app module, go ahead and add those as imports. And then it's kind of tedious to import those one at a time. So I typically just copy and paste the imports. Once you save that, it should build successfully. And then we can replace just that H1 with a Mac toolbar. And then in the car list component, we can use the card layout and card header and content and list items for each car, as well as eventually an avatar for the GIFI name. So now if we add some CSS, one of the themes from Angular Material, it'll look a lot better. Now you can see we have our list starting to look good, but we don't have the images in there. Well, that's because we haven't called out to GIFI to get them. So GIFI is a service that has a bunch of animated GIFs. And I wrote this service that we'll call GIFI with the car name or anything that you pass into it and fetch a GIF or URL for a GIF that matches that. So we create GIFI service.ts. And this uses a public beta key. So if you're planning on using this in production, I wouldn't recommend it. I would get your own API key. It limits it to only one image being returned. And you'll see that get method calls the API and just grabs the first image that comes back. We need to register GIFI service as a provider in our app module. And then in the car list component, you'll want to add it and loop through all the cars that come back from the car service and basically fetch their image. So add the GIFI service as a constructor dependency. And then we'll loop through all the cars and call GIFI service for each one. And now we actually have images coming back. Now let's edit them. So we'll create a new car edit component. And in order to do CRUD, we're gonna need get, save, and remove methods. So copy these from the tutorial into your car service. Still using HTTP client, but actually going and fetching the individual car ID, saving the individual car, whether it's new or update as a post or a put and remove as well. And so we'll add a link from our car list component to that edit screen using router link. And then we'll add an add button so we can actually create a new car. So let's see if that works. Oh, we haven't imported or configured routing yet. So in app module.ts, create a constant for the app routes, routes in some countries, and then import the routes component. And we'll use the four modules eventually, so go ahead and import that as well as the router module. And then in car edit component.ts, this is where the real meat of the application lies because it's going to render, it's going to allow you to save, it's gonna allow you to edit a car. So if you look at this class, it's got a constructor that takes a number of dependencies, activated route will allow you to get the parameter or the ID that's passed in. And then of course, car service and GIFI service will subscribe to the results and set the car locally. If there's an href, we know it's a car that's already exists. So we're just updating, not creating a new one. You'll want to unsubscribe from any subscriptions that you have and then the go to list goes back to the car list. And then we'll create an edit screen or modify the car edit.html to have form fields, and to use matcard and mat form field from Angular Material. We have a hidden field called href that will allow us to determine if it's an existing car or a new car. And then to make the image from GIFI look a little better, we'll just go ahead and add some CSS to give that a little bit of a margin. And then instead of using the app list component or the car list component, we'll use router outlet in the main app component. So at this point, you should have a list that's editable. You can add new cars. We'll do a Volkswagen bus, one of my favorites. You can even edit it. So all that's working, just fine and dandy. You can even delete. And so this is all good, but you might want authentication. So let's show you how to do that. With spring security, you can add OAuth support to the server side. So add the dependencies for spring boot starter security and spring security OAuth2 auto configure. And then you'll need to create an open ID connect application on Okta. You can sign up for a developer account at developer.okta.com if you don't already have one. I of course do. So I'll go ahead and sign into my tenant. I keep all my passwords in one password. So type that one in, 158606, and it logs me in. And I'll go ahead and create a new application. And it'll be a single page app. And I'll call it spring boot two and angular five. And we'll need to change all the URLs from 4200 or from 8080 to 4200. And then this client ID here down at the bottom we'll need eventually, but not right now. This is how you configure spring security to talk to OAuth on the server side when you're using spring boot. So it comes with an application.properties. Let's refactor that and rename it to application.yml or application.yml. Yet another markup language. Paste that in there. And then we'll need to populate that client ID. Copy it from our application and back into our application.yml. And then of course, tell IntelliJ to reimport everything so it recognizes those property names. And then also enable the server side as a resource server. So it looks for an authorization header that gets sent in from the client side and restart everything on the server. And now if we hit localhost 8080, we should see that it actually denies our access. So that's all working. And now we need to add security on the client side. So you can do that with octa's Angular SDK, which supports Angular 5. Our 1.0 version was just released. So I like to install specific versions. So npm install octa octa angular, the 1.0 version. And then in the app module, you can configure the properties for the issuer, for the redirect URI, and for the client ID. And that client ID is going to be the same one that we used on the server, so I'll just copy it from there. And then you'll need to add a new route for the callback after you come back from octa. And IntelliJ is not resolving that import, so I'll just go ahead and copy it from the tutorial. And then you need to initialize and import the octa auth module, which sets everything up. And now one of the things that can be handy, you don't have to do this, but I like to create an interceptor that adds the bearer token that comes back from octa to the header. So I'm going to create a new file called octa auth.interceptor.ts. I'll put this code in here, and you'll see here this implements HTTP interceptor. It has an intercept method, and then it calls this async handle access method that goes ahead and sets the bearer token. What's this problem here? No trailing whitespace, there we go. So that's fixed, and this will only send it to localhost because Githy's API fails, and you don't really want to send bearer tokens to just anyone. So then add this interceptor in app module and modify app component to have login and logout buttons. Finish importing everything. So you'll see this login button calls octa auth, login redirect, and the logout calls logout. So we're going to, oh, there's also this toolbar spacer here, which basically spreads things. Put some on the left, some on the right. So we can use a flex layout for that. Put it in our applicationcomponent.css. And then that is authenticated variable that determines whether to show login and logout can be set up in our app component. So this uses octa auth service, which we'll have to import, and it uses async and await to actually get that without using promises and dot then. And it also subscribes to the authentication state changing. Then we'll restart. So now if we look at our client, we'll go back to the main screen. You'll see we have a login button, but we still have that car list. So we kind of want to hide that. We just want to show login without an empty car list. So let's go ahead and create a new component called home. This will be our default route. And I'll just show the login button. So configure that in appmodule.ts as the default path. And then we'll move that logic for the login button into home.component.html. And then in the home component, we're gonna have to add a dependency on octa auth and set up that is authenticated logic or variable. So it actually works. Then we'll import. Usually IntelliJ will import this just fine, but it's not working for me today for some reason. And then modify app component. So it just shows that logout button and it also uses router link to go back to home when you click on it. So that's a handy feature. The click will still call that logout method, but the router link will also route afterwards. Now you should be able to open your browser to 4200. We still have it going here. So go back to 4200 and we'll see that login button. We can click on it and it'll route you to octa and we're logged in. If I clicked on this car list, I know that it won't work though because the cross origin annotation doesn't play well with spring security. So you do have to add a simple cores filter in the server demo application.java. And there are a couple of choices for the cores filter. So make sure you pick the spring one and then URL based cores configuration source. Make sure you pick the one that's non-reactive and then save that, restart your server and refresh your client, which probably isn't needed. Click the car list and everything's working. And you can even add a new car name. How about a Lambo? And then the Giffy image is always surprising and kind of awkward. So if you wanna see the source code for this application, it's on GitHub at octa spring boot two, Angular 5 example with all the instructions to clone the project and run it as well as create an OIDC app and configure the server and the client. There's a number of other related blog posts you can check out tutorials if you're interested both with Kotlin and TypeScript and OpenID Connect. If you're interested in octa, we have very simple pricing, 7,000 active users a month as a developer for free. And if you wanna upgrade to more users, you can easily do that. Thank you and hope you have a nice day.