Skip to content

Commit 6db70af

Browse files
author
hirsch88
committed
add new validation annotations
1 parent 7ac27fe commit 6db70af

File tree

2 files changed

+62
-20
lines changed

2 files changed

+62
-20
lines changed

src/api/services/UsersService.ts

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { injectable, inject, named } from 'inversify';
33
import { Repository } from '../../constants/Targets';
44
import { Types } from '../../constants/Types';
55
import { Log } from '../../core/log';
6+
import { Validate, Request } from '../../core/api/Validate';
67
import { NotFoundException } from '../exceptions/NotFoundException';
78
import { UserCreateRequest } from '../requests/UserCreateRequest';
89
import { UserUpdateRequest } from '../requests/UserUpdateRequest';
@@ -72,11 +73,8 @@ export class UserService {
7273
* @param {*} data is the json body of the request
7374
* @returns {Promise<User>}
7475
*/
75-
public async create(data: any): Promise<User> {
76-
// Validate request payload
77-
const request = new UserCreateRequest(data);
78-
await request.validate();
79-
76+
@Validate
77+
public async create( @Request(UserCreateRequest) data: any): Promise<User> {
8078
// If the request body was valid we will create the user
8179
const user = await this.userRepo.create(data);
8280
return user;
@@ -90,21 +88,17 @@ export class UserService {
9088
* @param {*} newUser is the json body of the request
9189
* @returns {Promise<User>}
9290
*/
93-
public async update(id: number, newUser: any): Promise<User> {
94-
const oldUserModel = await this.findOne(id);
95-
const oldUser = oldUserModel.toJSON();
96-
const request = new UserUpdateRequest(oldUser);
97-
98-
request.setFirstName(newUser.firstName);
99-
request.setLastName(newUser.lastName);
100-
request.setEmail(newUser.email);
101-
102-
// Validate request payload
103-
await request.validate();
104-
105-
// If the request body was valid we will create the user
106-
const user = await this.userRepo.update(id, request.toJSON());
107-
return user;
91+
@Validate
92+
public async update(id: number, @Request(UserUpdateRequest) newUser: any): Promise<User> {
93+
// Find or fail
94+
const user = await this.findOne(id);
95+
// Set new values
96+
user.FirstName = newUser.firstName;
97+
user.LastName = newUser.lastName;
98+
user.Email = newUser.email;
99+
// Update user record
100+
const updatedUser = await this.userRepo.update(id, user.toJSON());
101+
return updatedUser;
108102
}
109103

110104
/**

src/core/api/Validate.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { ValidationException } from '../../api/exceptions/ValidationException';
2+
import { RequestBody } from './RequestBody';
3+
4+
5+
const requestMetadataKey = Symbol('ValidateRequest');
6+
7+
interface RequestParameter {
8+
request: typeof RequestBody;
9+
index: number;
10+
}
11+
12+
/**
13+
* Request annotation marks the parameters, which should be validated as a RequestBody.
14+
*
15+
* @param request
16+
*/
17+
export const Request = (request: typeof RequestBody) => (target: Object, propertyKey: string | symbol, parameterIndex: number): any => {
18+
const existingRequestParameters: RequestParameter[] = Reflect.getOwnMetadata(requestMetadataKey, target, propertyKey) || [];
19+
existingRequestParameters.push({
20+
request: request,
21+
index: parameterIndex
22+
});
23+
Reflect.defineMetadata(requestMetadataKey, existingRequestParameters, target, propertyKey);
24+
};
25+
26+
/**
27+
* Validate annotation builds the given RequestBodies and validates them
28+
*
29+
* @param target
30+
* @param propertyName
31+
* @param descriptor
32+
*/
33+
export const Validate = (target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>): any => {
34+
const method = descriptor.value;
35+
descriptor.value = async function (...args: any[]): Promise<any> {
36+
const requestParameters: RequestParameter[] = Reflect.getOwnMetadata(requestMetadataKey, target, propertyName);
37+
if (requestParameters.length > 0) {
38+
for (let i = 0; i < requestParameters.length; i++) {
39+
const requestParameter: RequestParameter = requestParameters[i];
40+
const request = new requestParameter.request(args[requestParameter.index]);
41+
await request.validate();
42+
}
43+
}
44+
return method.apply(this, args);
45+
};
46+
47+
return descriptor;
48+
};

0 commit comments

Comments
 (0)