프로그래밍(Web)/Javascript(TS,Node)
[바미] Typescript-restful-starter - Update 될 때 텍스트뿐만 아니라 이메일도 수정 할 수 있게 변경하기!
Bami
2020. 12. 22. 17:25
728x90
반응형
코드 수정 전
Sample.schemas.ts
import { number, object, string } from "joi";
/* 구조 정의 */
export const createSample = object().keys({
text: string().required(),
email: string().required(),
});
export const updateSample = object().keys({
id: number().required(),
text: string().required(),
});
export const deleteSample = object().keys({
id: number().required(),
});
코드 수정 후
Sample.schemas.ts
import { number, object, string } from "joi";
/* 구조 정의 */
export const createSample = object().keys({
text: string().required(),
email: string().required(),
});
export const updateSample = object().keys({
id: number().required(),
text: string().required(),
email: string().required(), // 추가
});
export const deleteSample = object().keys({
id: number().required(),
});
변경 전 List
출력화면
Tester
Web
- 두 번째 코드 수정
- get으로 id로 검색외에 text, email로 검색된 데이터 출력.
코드 수정 전
Sample.test.ts
변수 선언
let IdRecord: number;
기능 예제
//... 중략
it("Can search for Sample by Id", (done) => {
supertest(app).get(`/find/id/:${IdRecord}`)
.set("Authorization", `bearer ${token}`).set("Accept", "application/json")
.end((err: Error, res: supertest.Response) => {
chai.expect(res.status).to.eq(200);
chai.expect(res.body).to.be.a("object");
chai.expect(res.body).to.have.all.keys("id", "text", "email");
chai.expect(res.body.text).to.be.a("string");
done();
});
});
Sample.repository.ts
import { EntityRepository, Repository } from "typeorm";
import { Sample } from "../models";
@EntityRepository(Sample)
export class SampleRepository extends Repository<Sample> {
public bulkCreate(Samples: Sample[]): Promise<any> {
return this.manager.createQueryBuilder().insert().into(Sample).values(Samples).execute();
}
public async removeById(id: number): Promise<Sample> {
const itemToRemove: Sample = await this.findOne({id});
return this.manager.remove(itemToRemove);
}
public findByText(text: string): Promise<Sample[]> {
return this.manager.find(Sample, {where: {text}});
}
public findOneById(id: number): Promise<Sample> {
return this.manager.findOne(Sample, {where: {id}});
}
}
Sample.service.ts
import { getCustomRepository } from "typeorm";
import { Sample } from "../models";
import { SampleRepository } from "../repository";
export class SampleService {
public findByText(text: string): Promise<Sample[]> {
return getCustomRepository(SampleRepository).findByText(text);
}
public findByEmail(email: string): Promise<Sample[]> {
return getCustomRepository(SampleRepository).findByEmail(email);
}
public bulkCreate(Samples: Sample[]): Promise<Sample[]> {
return getCustomRepository(SampleRepository).bulkCreate(Samples);
}
public findOneById(id: number): Promise<Sample> {
return getCustomRepository(SampleRepository).findOneById(id);
}
public find(): Promise<Sample[]> {
return getCustomRepository(SampleRepository).find();
}
public remove(sample: Sample): Promise<Sample> {
return getCustomRepository(SampleRepository).remove(sample);
}
public removeById(id: number): Promise<Sample> {
return getCustomRepository(SampleRepository).removeById(id);
}
public save(sample: Sample): Promise<Sample> {
return getCustomRepository(SampleRepository).save(sample);
}
}
Sample.route.ts
import { SampleController } from "../controllers";
import { Validator } from "../middlewares";
import { createSample, deleteSample, updateSample } from "../schemas";
import { Router } from "./Router";
/* Method 방식에 따른 처리
.get("/",...) - get방식에서 '/'이후 아무것도 입력하지 않았을 때 'createSample'을 통해 만들어진 데이터들이 리스트로 출력된다.
.get("/:id", ...) - get방식에서 '/'옆에 id값을 입력 시 해당 id값의 데이터를 출력시켜준다. ex: http://localhost:8080/2
.post("/", ...) - post방식에서 Sample.schemas.ts의 형식에 맞게 json값을 입력 시 id, text, eamil 값이 DB에 생성된다. (현재는 임의적인 text값만 주면 생성된다.)
.put("/", ...) - put 방식에서 id값을 json방식으로 입력 시 해당 id값이 삭제된다. (routes/Sample.route.ts에서 )
*/
export class SampleRouter extends Router {
constructor() {
super(SampleController);
this.router
.get("/", this.handler(SampleController.prototype.all))
.get("/:id", this.handler(SampleController.prototype.find))
.post("/", [ Validator(createSample) ], this.handler(SampleController.prototype.create))
.put("/", [ Validator(updateSample) ], this.handler(SampleController.prototype.update))
.delete("/", [ Validator(deleteSample) ], this.handler(SampleController.prototype.delete));
}
}
코드 수정 후
Sample.test.ts
변수 선언
let IdRecord: number;
let textRecord: string; // 조회할 text값을 받는 변수(추가)
let emailRecord: string; // 조회할 email값을 받는 변수(추가)
기능 예제
//... 중략
it("Can search for Sample by Id", (done) => {
supertest(app).get(`/find/id/:${IdRecord}`)
.set("Authorization", `bearer ${token}`).set("Accept", "application/json")
.end((err: Error, res: supertest.Response) => {
chai.expect(res.status).to.eq(200);
chai.expect(res.body).to.be.a("object");
chai.expect(res.body).to.have.all.keys("id", "text", "email");
chai.expect(res.body.text).to.be.a("string");
done();
});
});
it("Can search for Sample by Text", (done) => { // text검색기능
supertest(app).get(`/find/text/:${textRecord}`)
.set("Authorization", `bearer ${token}`).set("Accept", "application/json")
.end((err: Error, res: supertest.Response) => {
chai.expect(res.status).to.eq(200);
chai.expect(res.body).to.be.a("object");
chai.expect(res.body).to.have.all.keys("id", "text", "email");
chai.expect(res.body.text).to.be.a("string");
done();
});
});
it("Can search for Sample by Email", (done) => { // email검색기능
supertest(app).get(`/find/email/:${emailRecord}`)
.set("Authorization", `bearer ${token}`).set("Accept", "application/json")
.end((err: Error, res: supertest.Response) => {
chai.expect(res.status).to.eq(200);
chai.expect(res.body).to.be.a("object");
chai.expect(res.body).to.have.all.keys("id", "text", "email");
chai.expect(res.body.text).to.be.a("string");
done();
});
});
Sample.repository.ts
import { EntityRepository, Repository } from "typeorm";
import { Sample } from "../models";
@EntityRepository(Sample)
export class SampleRepository extends Repository<Sample> {
public bulkCreate(Samples: Sample[]): Promise<any> {
return this.manager.createQueryBuilder().insert().into(Sample).values(Samples).execute();
}
public async removeById(id: number): Promise<Sample> {
const itemToRemove: Sample = await this.findOne({id});
return this.manager.remove(itemToRemove);
}
public findByText(text: string): Promise<Sample[]> {
return this.manager.find(Sample, {where: {text}});
}
// 입력받은 email과 DB안에 저장되어 있는 email이 같은 값이 있는지 조회. (추가)
public findByEmail(email: string): Promise<Sample[]> {
return this.manager.find(Sample, {where: {email}});
}
public findOneById(id: number): Promise<Sample> {
return this.manager.findOne(Sample, {where: {id}});
}
}
Sample.service.ts
import { getCustomRepository } from "typeorm";
import { Sample } from "../models";
import { SampleRepository } from "../repository";
export class SampleService {
public findByText(text: string): Promise<Sample[]> {
return getCustomRepository(SampleRepository).findByText(text);
}
public findByEmail(email: string): Promise<Sample[]> {
return getCustomRepository(SampleRepository).findByEmail(email);
}
public bulkCreate(Samples: Sample[]): Promise<Sample[]> {
return getCustomRepository(SampleRepository).bulkCreate(Samples);
}
public findOneById(id: number): Promise<Sample> {
return getCustomRepository(SampleRepository).findOneById(id);
}
public find(): Promise<Sample[]> {
return getCustomRepository(SampleRepository).find();
}
public remove(sample: Sample): Promise<Sample> {
return getCustomRepository(SampleRepository).remove(sample);
}
public removeById(id: number): Promise<Sample> {
return getCustomRepository(SampleRepository).removeById(id);
}
public save(sample: Sample): Promise<Sample> {
return getCustomRepository(SampleRepository).save(sample);
}
}
Sample.route.ts
import { SampleController } from "../controllers";
import { Validator } from "../middlewares";
import { createSample, deleteSample, updateSample } from "../schemas";
import { Router } from "./Router";
export class SampleRouter extends Router {
constructor() {
super(SampleController);
this.router
.get("/", this.handler(SampleController.prototype.all))
.get("/find/text/:text", this.handler(SampleController.prototype.find)) // text 찾는 route
.get("/find/id/:id", this.handler(SampleController.prototype.find2)) // id 찾는 route
.get("/find/email/:email", this.handler(SampleController.prototype.find3)) // email 찾는 route
.post("/", [ Validator(createSample) ], this.handler(SampleController.prototype.create))
.put("/", [ Validator(updateSample) ], this.handler(SampleController.prototype.update))
.delete("/", [ Validator(deleteSample) ], this.handler(SampleController.prototype.delete));
}
}
출력화면
Tester
-
id로 검색 시
-
text로 검색 시
-
email로 검색 시
note(remind)
원래 의도는 id검색 외에도 text를 검색하게 하고 싶었다.
그래서 Sample.service.ts, Sample.test.ts,등 4군데 코드를 수정 및 추가했다.
하지만 의도와는 다르게 text로만 검색이 될 뿐 id로는 검색이 되지 않았다.
문제의 원인은
.get("/:text", this.handler(SampleController.prototype.find))
.get("/:id", this.handler(SampleController.prototype.find2))
로만 해서 서로의 경로가 겹쳤기 때문이였다. 위와 같이 하면 text값과 id값을 분리시켜 검색 될 줄 알았기 때문이다.
그래서 Sample.route.ts에서
.get("/find/text/:text", this.handler(SampleController.prototype.find))
.get("/find/id/:id", this.handler(SampleController.prototype.find2))
으로 수정하였고, 경로 또한 더 명확하게 구별 시켜주었다. 그래서 이를 더 응용하여 eamil 까지 검색 하는 기능을 구현했다.
728x90
반응형