Rest API Service를 이용한 Angular4 Application Step2.
2018/04/11 - [개발/Java] - Rest API Service를 이용한 Angular4 Application 작성1
1. Angular Project를 생성한다.
- ng new user-app --routing 명령어로 생성(routing 모듈을 기본적으로 생성하는 옵션)
D:\itdev4u\angular>ng new user-app --routing create user-app/e2e/app.e2e-spec.ts (290 bytes) create user-app/e2e/app.po.ts (208 bytes) create user-app/e2e/tsconfig.e2e.json (235 bytes) create user-app/karma.conf.js (923 bytes) create user-app/package.json (1293 bytes) create user-app/protractor.conf.js (722 bytes) create user-app/README.md (1023 bytes) create user-app/tsconfig.json (363 bytes) create user-app/tslint.json (3012 bytes) create user-app/.angular-cli.json (1243 bytes) create user-app/.editorconfig (245 bytes) create user-app/.gitignore (544 bytes) create user-app/src/assets/.gitkeep (0 bytes) create user-app/src/environments/environment.prod.ts (51 bytes) create user-app/src/environments/environment.ts (387 bytes) create user-app/src/favicon.ico (5430 bytes) create user-app/src/index.html (294 bytes) create user-app/src/main.ts (370 bytes) create user-app/src/polyfills.ts (3114 bytes) create user-app/src/styles.css (80 bytes) create user-app/src/test.ts (642 bytes) create user-app/src/tsconfig.app.json (211 bytes) create user-app/src/tsconfig.spec.json (283 bytes) create user-app/src/typings.d.ts (104 bytes) create user-app/src/app/app-routing.module.ts (245 bytes) create user-app/src/app/app.module.ts (395 bytes) create user-app/src/app/app.component.html (1173 bytes) create user-app/src/app/app.component.spec.ts (1103 bytes) create user-app/src/app/app.component.ts (207 bytes) create user-app/src/app/app.component.css (0 bytes) npm WARN deprecated nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/ npm WARN deprecated mailcomposer@4.0.1: This project is unmaintained npm WARN deprecated socks@1.1.9: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0 npm WARN deprecated node-uuid@1.4.8: Use uuid module instead npm WARN deprecated buildmail@4.0.1: This project is unmaintained npm WARN deprecated socks@1.1.10: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0 > uws@9.14.0 install D:\itdev4u\angular\user-app\node_modules\uws > node-gyp rebuild > build_log.txt 2>&1 || exit 0 > node-sass@4.8.3 install D:\itdev4u\angular\user-app\node_modules\node-sass > node scripts/install.js Cached binary found at C:\Users\lunajin\AppData\Roaming\npm-cache\node-sass\4.8.3\win32-x64-59_binding.node > uglifyjs-webpack-plugin@0.4.6 postinstall D:\itdev4u\angular\user-app\node_modules\webpack\node_modules\uglifyjs-webpack-plugin > node lib/post_install.js > node-sass@4.8.3 postinstall D:\itdev4u\angular\user-app\node_modules\node-sass > node scripts/build.js Binary found at D:\itdev4u\angular\user-app\node_modules\node-sass\vendor\win32-x64-59\binding.node Testing binary Binary is fine npm WARN rollback Rolling back ajv@4.11.8 failed (this is probably harmless): EPERM: operation not permitted, lstat 'D:\itdev4u\angular\user-app\node_modules\fsevents\node_modules' npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) added 1259 packages in 150.629s 'git'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. Project 'user-app' successfully created.
2. user module을 생성한다.
- ng generate module user --routing 명령어로 생성.
D:\itdev4u\angular\user-app>ng generate module user --routing create src/app/user/user-routing.module.ts (247 bytes) create src/app/user/user.module.ts (271 bytes)
3. Rest API Service를 호출할때 필요한 user service를 생성한다.
- ng generate service user/user 명령어로 user module내에 생성.
D:\itdev4u\angular\user-app>ng generate service user/user create src/app/user/user.service.spec.ts (362 bytes) create src/app/user/user.service.ts (110 bytes)
4. user모듈내에 sub component를 생성한다.
- user-list component : 사용자 목록 관련 component
- user-create component : 사용자 생성/수정 관련 component
- ng generate component user/user-list 명령어로 생성
- ng generate component user/user-create 명령어로 생성
D:\itdev4u\angular\user-app>ng generate component user/user-list create src/app/user/user-list/user-list.component.html (28 bytes) create src/app/user/user-list/user-list.component.spec.ts (643 bytes) create src/app/user/user-list/user-list.component.ts (280 bytes) create src/app/user/user-list/user-list.component.css (0 bytes) update src/app/user/user.module.ts (357 bytes) D:\itdev4u\angular\user-app>ng generate component user/user-create create src/app/user/user-create/user-create.component.html (30 bytes) create src/app/user/user-create/user-create.component.spec.ts (657 bytes) create src/app/user/user-create/user-create.component.ts (288 bytes) create src/app/user/user-create/user-create.component.css (0 bytes) update src/app/user/user.module.ts (453 bytes)
5. Url 기반으로 관련페이지 리다이렉션등의 액션을 위해 user-routing.module.ts 파일을 수정한다.
- src/app/user/user-routing.module.ts 파일 수정.
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { UserListComponent } from './user-list/user-list.component'; import { UserCreateComponent } from './user-create/user-create.component'; const routes: Routes = [ {path: 'user', component: UserListComponent}, {path: 'user/create', component: UserCreateComponent}, {path: 'user/edit/:id', component: UserCreateComponent} ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class UserRoutingModule { }
6. app.module.ts 파일에 UserModule을 import한다.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { UserModule } from './user/user.module'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, UserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
7. bootstrap4 project를 추가한다.
- npm install --save bootstrap font-awesome 명령어로 추가.
D:\itdev4u\angular\user-app>npm install --save bootstrap font-awesome npm WARN bootstrap@4.1.0 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself. npm WARN bootstrap@4.1.0 requires a peer of popper.js@^1.14.0 but none is installed. You must install peer dependencies yourself. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) + bootstrap@4.1.0 + font-awesome@4.7.0 added 2 packages in 32.983s
8. bootstrap style을 적용한다.
- src/style.css 파일을 수정.
/* You can add global styles to this file, and also import other style files */ @import "~bootstrap/dist/css/bootstrap.min.css"; @import "~font-awesome/css/font-awesome.css";
9. 사용자정보를 표시할 User class를 생성한다.
- src/app/user/user.ts 파일을 생성.
export class User { id: number; firstname: string; lastname: string; email: string; constructor(id: number, firstname: string, lastname: string, email: string) { this.id = id; this.firstname = firstname; this.lastname = lastname; this.email = email; } }
10. Rest API와 연동하는 서비스를 수정한다.
- src/app/user/user.service.ts 파일 수정.
import { Injectable } from '@angular/core'; import { User } from './user'; import { Http, Response } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/catch'; import { Observable } from 'rxjs/Observable'; @Injectable() export class UserService { private apiUrl = 'http://localhost:8080/api'; constructor(private http: Http) { } findAll(): Observable{ console.log('Start findAll'); return this.http.get(this.apiUrl + '/users') .map((res: Response) => res.json()) .catch((error: any) => Observable.throw(error.json().error || 'Server error')); } findById(id: number): Observable { return null; } saveUser(user: User): Observable { return null; } deleteUserById(id: number): Observable { return null; } updateUser(user: User): Observable { return null; } }
11. 전체사용자를 조회하는 서비스를 호출할 수 있게 user-list.component.ts 파일을 수정한다.
- src/app/user/user-list/user-list.component.ts 파일 수정.
import { Component, OnInit } from '@angular/core'; import { User } from '../user'; import { UserService } from '../user.service'; @Component({ selector: 'app-user-list', templateUrl: './user-list.component.html', styleUrls: ['./user-list.component.css'], providers: [UserService] }) export class UserListComponent implements OnInit { private users: User[]; constructor(private userService: UserService) { } ngOnInit() { this.getAllUsers(); } getAllUsers() { this.userService.findAll().subscribe( users => { this.users = users; }, err => { console.log(err); } ); } }
12. 전체사용자 목록을 보여주는 template 파일을 수정한다.
- src/app/user/user-list/user-list.component.html 파일을 수정.
<div class="container"> <div class="row"> <div class="col"> <section> <header class="header"> <div class="row"> <div class="col-md-4"> <h1>Users</h1> </div> <div class="col-md-6"> </div> <div class="col-md-2"> <button type="button" class="btn btn-primary" (click)="redirectNewUserPage()">New User</button> </div> </div> </header> </section> <section class="main"> <table class="table"> <thead> <tr> <th>#</th> <th>First Name</th> <th>Last Name</th> <th>email</th> <th></th> </tr> </thead> <tbody> <tr *ngFor="let user of users"> <th scope="row">{{user.id}}</th> <td>{{user.firstname}}</td> <td>{{user.lastname}}</td> <td>{{user.email}}</td> <td> <button type="button" class="btn btn-success" (click)="editUserPage(user)">Edit</button> <button type="button" class="btn btn-danger" (click)="deleteUser(user)">Delete</button> </td> </tr> </tbody> </table> </section> </div> </div> </div>
13. app.module.ts 파일에 HttpModule을 import한다.
- src/app/app.module.ts 파일 수정.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { UserModule } from './user/user.module'; import { HttpModule } from '@angular/http'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, UserModule, HttpModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
14. Spring에서 CROS를 활성화하기 위해 Rest API Service의 Controller파일에 설정을 추가한다.
- com.itdev4u.controller.UserController 파일에 @CrossOrigin(origins = http://localhost:4200) 추가.
package com.itdev4u.controller; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.itdev4u.exception.ResourceNotFoundException; import com.itdev4u.model.User; import com.itdev4u.repository.UserRepository; @CrossOrigin(origins = "http://localhost:4200") @RestController @RequestMapping("/api") public class UserController { @Autowired UserRepository userRepository; //Get All User @GetMapping("/users") public ListgetAllUsers() { return userRepository.findAll(); } //Create a new User @PostMapping("/user") public User createUser(@Valid @RequestBody User user) { return userRepository.save(user); } //Get a Single User @GetMapping("/user/{id}") public User getUserById(@PathVariable(value = "id") Long userId) { return userRepository.findById(userId) .orElseThrow(()->new ResourceNotFoundException("User", "id", userId)); } //Update User @PutMapping("/user/{id}") public User updateUser(@PathVariable(value = "id") Long userId , @Valid @RequestBody User userDetail) { User user = userRepository.findById(userId) .orElseThrow(()->new ResourceNotFoundException("User", "id", userId)); user.setFirstname(userDetail.getFirstname()); user.setLastname(userDetail.getLastname()); user.setEmail(userDetail.getEmail()); User updateUser = userRepository.save(user); return updateUser; } //Delete a User @DeleteMapping("/user/{id}") public ResponseEntity> deleteUser(@PathVariable(value = "id") Long userId) { User user = userRepository.findById(userId) .orElseThrow(()->new ResourceNotFoundException("User", "id", userId)); userRepository.delete(user); return ResponseEntity.ok().build(); } }
'개발 > Java' 카테고리의 다른 글
Rest API Service를 이용한 Angular4 Application 작성1 (0) | 2018.04.11 |
---|---|
[Spring Boot] JPA Restful CRUD API Sample2 (0) | 2018.04.09 |
[Spring Boot] JPA Restful CRUD API Sample1 (0) | 2018.04.08 |
Spring RESTFul Web Service (0) | 2018.04.06 |
Spring Data JPA 1 (0) | 2018.04.04 |