diff --git a/src/server/api/call.ts b/src/server/api/call.ts
index b87707c34830514ec485b9d4d55a36db4ec531da..673d44919941676cab5f74ca363896118f389f2e 100644
--- a/src/server/api/call.ts
+++ b/src/server/api/call.ts
@@ -42,18 +42,12 @@ export default (endpoint: string, user: IUser, app: IApp, data: any, file?: any)
 		}
 	}
 
-	let exec = ep.exec;
-
-	if (ep.meta.requireFile && file) {
-		exec = exec.bind(null, file);
-	}
-
 	let res;
 
 	// API invoking
 	try {
 		const before = performance.now();
-		res = await exec(data, user, app);
+		res = await ep.exec(data, user, app, file);
 		const after = performance.now();
 
 		const time = after - before;
diff --git a/src/server/api/define.ts b/src/server/api/define.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c66ade5fdaeb6b2eae71cd6ccacac9e00e464e00
--- /dev/null
+++ b/src/server/api/define.ts
@@ -0,0 +1,51 @@
+import * as fs from 'fs';
+import { ILocalUser } from '../../models/user';
+import { IApp } from '../../models/app';
+import { IEndpointMeta } from './endpoints';
+
+type Params<T extends IEndpointMeta> = {
+	[P in keyof T['params']]: T['params'][P]['transform'] extends Function
+		? ReturnType<T['params'][P]['transform']>
+		: ReturnType<T['params'][P]['validator']['get']>[0];
+};
+
+export default function <T extends IEndpointMeta>(meta: T, cb: (params: Params<T>, user: ILocalUser, app: IApp, file?: any, cleanup?: Function) => Promise<any>): (params: any, user: ILocalUser, app: IApp, file?: any) => Promise<any> {
+	return (params: any, user: ILocalUser, app: IApp, file?: any) => {
+		function cleanup() {
+			fs.unlink(file.path, () => {});
+		}
+
+		if (meta.requireFile && file == null) return Promise.reject('file required');
+
+		const [ps, pserr] = getParams(meta, params);
+		if (pserr) {
+			if (file) cleanup();
+			return Promise.reject(pserr);
+		}
+
+		return cb(ps, user, app, file, cleanup);
+	};
+}
+
+function getParams<T extends IEndpointMeta>(defs: T, params: any): [Params<T>, Error] {
+	const x: any = {};
+	let err: Error = null;
+	Object.entries(defs.params).some(([k, def]) => {
+		const [v, e] = def.validator.get(params[k]);
+		if (e) {
+			err = new Error(e.message);
+			err.name = 'INVALID_PARAM';
+			(err as any).param = k;
+			return true;
+		} else {
+			if (v === undefined && def.default) {
+				x[k] = def.default;
+			} else {
+				x[k] = v;
+			}
+			if (def.transform) x[k] = def.transform(x[k]);
+			return false;
+		}
+	});
+	return [x, err];
+}
diff --git a/src/server/api/endpoints/admin/invite.ts b/src/server/api/endpoints/admin/invite.ts
index 892b2579f22cfea2c4b106b40073af79ced4118d..056cb8aa75de86170ae94ffa4011b32ed0d9b04b 100644
--- a/src/server/api/endpoints/admin/invite.ts
+++ b/src/server/api/endpoints/admin/invite.ts
@@ -1,5 +1,6 @@
 import rndstr from 'rndstr';
 import RegistrationTicket from '../../../../models/registration-tickets';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -12,7 +13,7 @@ export const meta = {
 	params: {}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const code = rndstr({ length: 5, chars: '0-9' });
 
 	await RegistrationTicket.insert({
@@ -23,4 +24,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 	res({
 		code: code
 	});
-});
+}));
diff --git a/src/server/api/endpoints/admin/suspend-user.ts b/src/server/api/endpoints/admin/suspend-user.ts
index 6d8b28932fd8065d2ca75434848b781e1446ee8f..0ad0aab74ccd72fbe04111d2889cf827c1c3035c 100644
--- a/src/server/api/endpoints/admin/suspend-user.ts
+++ b/src/server/api/endpoints/admin/suspend-user.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../misc/cafy-id';
-import getParams from '../../get-params';
+import define from '../../define';
 import User from '../../../../models/user';
 
 export const meta = {
@@ -24,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const user = await User.findOne({
 		_id: ps.userId
 	});
@@ -49,4 +46,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/admin/unsuspend-user.ts b/src/server/api/endpoints/admin/unsuspend-user.ts
index 5c736122bba963a289e429788d06f3aa885fb755..7c5eedee46bdb1f1f9e91ab80f881ed2be9d2d86 100644
--- a/src/server/api/endpoints/admin/unsuspend-user.ts
+++ b/src/server/api/endpoints/admin/unsuspend-user.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../misc/cafy-id';
-import getParams from '../../get-params';
+import define from '../../define';
 import User from '../../../../models/user';
 
 export const meta = {
@@ -24,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const user = await User.findOne({
 		_id: ps.userId
 	});
@@ -45,4 +42,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/admin/unverify-user.ts b/src/server/api/endpoints/admin/unverify-user.ts
index fc55bd74764300cda26e496368f11aa6e88481c0..d749e002e3fe72d1a2dea6a61975f0f2a6477778 100644
--- a/src/server/api/endpoints/admin/unverify-user.ts
+++ b/src/server/api/endpoints/admin/unverify-user.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../misc/cafy-id';
-import getParams from '../../get-params';
+import define from '../../define';
 import User from '../../../../models/user';
 
 export const meta = {
@@ -24,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const user = await User.findOne({
 		_id: ps.userId
 	});
@@ -45,4 +42,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/admin/update-meta.ts b/src/server/api/endpoints/admin/update-meta.ts
index aed53e12ce4b0a381b397cd5ba99ead0ab1a9789..c2bb107f8713c9f771b53e7340ae47a570ee62fb 100644
--- a/src/server/api/endpoints/admin/update-meta.ts
+++ b/src/server/api/endpoints/admin/update-meta.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import Meta from '../../../../models/meta';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -55,10 +55,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const set = {} as any;
 
 	if (ps.broadcasts) {
@@ -90,4 +87,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 	}, { upsert: true });
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/admin/verify-user.ts b/src/server/api/endpoints/admin/verify-user.ts
index b8c0bbaa8df98c204092c8fd541538454e8ce733..09efc2e803439ff614de310d56f61eff6af6267e 100644
--- a/src/server/api/endpoints/admin/verify-user.ts
+++ b/src/server/api/endpoints/admin/verify-user.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../misc/cafy-id';
-import getParams from '../../get-params';
+import define from '../../define';
 import User from '../../../../models/user';
 
 export const meta = {
@@ -24,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const user = await User.findOne({
 		_id: ps.userId
 	});
@@ -45,4 +42,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/ap/show.ts b/src/server/api/endpoints/ap/show.ts
index c5286583d00b95a9f980e6e4f60e99c9aedf6c5e..778d1e5099af9a534eb04f5edbeb76c2bcf2f099 100644
--- a/src/server/api/endpoints/ap/show.ts
+++ b/src/server/api/endpoints/ap/show.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import config from '../../../../config';
 import * as mongo from 'mongodb';
 import User, { pack as packUser, IUser } from '../../../../models/user';
@@ -25,15 +25,12 @@ export const meta = {
 	},
 };
 
-export default async (params: any) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const object = await fetchAny(ps.uri);
-	if (object !== null) return object;
+	if (object == null) return rej('object not found');
 
-	throw new Error('object not found');
-};
+	res(object);
+}));
 
 /***
  * URIからUserかNoteを解決する
diff --git a/src/server/api/endpoints/app/create.ts b/src/server/api/endpoints/app/create.ts
index 40da5144f676bb8d351eb6a7bafaa5a7e909ebc6..af66bb9d5ac1ec004bf9178783ede71387576a87 100644
--- a/src/server/api/endpoints/app/create.ts
+++ b/src/server/api/endpoints/app/create.ts
@@ -1,8 +1,7 @@
 import rndstr from 'rndstr';
 import $ from 'cafy';
 import App, { pack } from '../../../../models/app';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -28,10 +27,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Generate secret
 	const secret = rndstr('a-zA-Z0-9', 32);
 
@@ -51,4 +47,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 		detail: true,
 		includeSecret: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/app/show.ts b/src/server/api/endpoints/app/show.ts
index 0d73985b4804d5c487c399ed3544632314e83747..21e6350113e74ac66490dce2ec69bf8656a88562 100644
--- a/src/server/api/endpoints/app/show.ts
+++ b/src/server/api/endpoints/app/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import App, { pack, IApp } from '../../../../models/app';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import App, { pack } from '../../../../models/app';
+import define from '../../define';
 
 export const meta = {
 	params: {
@@ -12,10 +11,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
 	const isSecure = user != null && app == null;
 
 	// Lookup app
@@ -30,4 +26,4 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
 		detail: true,
 		includeSecret: isSecure && ap.userId.equals(user._id)
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/auth/accept.ts b/src/server/api/endpoints/auth/accept.ts
index ed1c2fa3903531b4e3c726e35d2a5f7913fc567d..b7e11bd46303c589a8c414a7cd0b1d2cb5d78789 100644
--- a/src/server/api/endpoints/auth/accept.ts
+++ b/src/server/api/endpoints/auth/accept.ts
@@ -4,8 +4,7 @@ import $ from 'cafy';
 import App from '../../../../models/app';
 import AuthSess from '../../../../models/auth-session';
 import AccessToken from '../../../../models/access-token';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -19,10 +18,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch token
 	const session = await AuthSess
 		.findOne({ token: ps.token });
@@ -70,4 +66,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Response
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/auth/session/generate.ts b/src/server/api/endpoints/auth/session/generate.ts
index 79eb34d96abd8404acf2af217eab15e8d2c1ab43..5ef3404b73b41069fc17030bdadca8fc2b078ae5 100644
--- a/src/server/api/endpoints/auth/session/generate.ts
+++ b/src/server/api/endpoints/auth/session/generate.ts
@@ -3,7 +3,7 @@ import $ from 'cafy';
 import App from '../../../../../models/app';
 import AuthSess from '../../../../../models/auth-session';
 import config from '../../../../../config';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -15,10 +15,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	// Lookup app
 	const app = await App.findOne({
 		secret: ps.appSecret
@@ -43,4 +40,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		token: doc.token,
 		url: `${config.auth_url}/${doc.token}`
 	});
-});
+}));
diff --git a/src/server/api/endpoints/auth/session/show.ts b/src/server/api/endpoints/auth/session/show.ts
index 9e7f4f52d4712c263556896d54d08752c914b420..cc63c43ad32389184812dc0bbaef8680b4acc176 100644
--- a/src/server/api/endpoints/auth/session/show.ts
+++ b/src/server/api/endpoints/auth/session/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy';
 import AuthSess, { pack } from '../../../../../models/auth-session';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -13,10 +12,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Lookup session
 	const session = await AuthSess.findOne({
 		token: ps.token
@@ -28,4 +24,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Response
 	res(await pack(session, user));
-});
+}));
diff --git a/src/server/api/endpoints/auth/session/userkey.ts b/src/server/api/endpoints/auth/session/userkey.ts
index 50edf12abc794ecb439d9051d1fd6463d8b35163..9f924d27a01fa9f68cb73ab4726e192661f8cac9 100644
--- a/src/server/api/endpoints/auth/session/userkey.ts
+++ b/src/server/api/endpoints/auth/session/userkey.ts
@@ -3,7 +3,7 @@ import App from '../../../../../models/app';
 import AuthSess from '../../../../../models/auth-session';
 import AccessToken from '../../../../../models/access-token';
 import { pack } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	// Lookup app
 	const app = await App.findOne({
 		secret: ps.appSecret
@@ -71,4 +68,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 			detail: true
 		})
 	});
-});
+}));
diff --git a/src/server/api/endpoints/blocking/create.ts b/src/server/api/endpoints/blocking/create.ts
index 7ec01b4237af627ffae58914a472959cd0bffe56..7166505309b459237c0fb6e70e7cc8e36b2ad104 100644
--- a/src/server/api/endpoints/blocking/create.ts
+++ b/src/server/api/endpoints/blocking/create.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 const ms = require('ms');
-import User, { pack, ILocalUser } from '../../../../models/user';
+import User, { pack } from '../../../../models/user';
 import Blocking from '../../../../models/blocking';
 import create from '../../../../services/blocking/create';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -34,10 +34,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const blocker = user;
 
 	// 自分自身
@@ -76,4 +73,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await pack(blockee._id, user, {
 		detail: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/blocking/delete.ts b/src/server/api/endpoints/blocking/delete.ts
index adf8d8c500e20c9ea266767fdd9ea5feb22d227d..667255a66b26f294de2e0612856ad08c50c78808 100644
--- a/src/server/api/endpoints/blocking/delete.ts
+++ b/src/server/api/endpoints/blocking/delete.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 const ms = require('ms');
-import User, { pack, ILocalUser } from '../../../../models/user';
+import User, { pack } from '../../../../models/user';
 import Blocking from '../../../../models/blocking';
 import deleteBlocking from '../../../../services/blocking/delete';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -34,10 +34,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const blocker = user;
 
 	// Check if the blockee is yourself
@@ -76,4 +73,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await pack(blockee._id, user, {
 		detail: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/blocking/list.ts b/src/server/api/endpoints/blocking/list.ts
index 52f55805d0d54726f0c60f56aa5d5d130bd3b973..e2649573d57548bb3754b9df2713103fa201fd59 100644
--- a/src/server/api/endpoints/blocking/list.ts
+++ b/src/server/api/endpoints/blocking/list.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Blocking, { packMany } from '../../../../models/blocking';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -31,10 +30,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -66,4 +62,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		});
 
 	res(await packMany(blockings, me));
-});
+}));
diff --git a/src/server/api/endpoints/charts/drive.ts b/src/server/api/endpoints/charts/drive.ts
index 22000813309790bbf158618815442c86825c7171..ca0b6c53d2d38270e903fff3cd237448829e05f7 100644
--- a/src/server/api/endpoints/charts/drive.ts
+++ b/src/server/api/endpoints/charts/drive.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import driveChart from '../../../../chart/drive';
 
 export const meta = {
@@ -25,11 +25,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await driveChart.getChart(ps.span as any, ps.limit);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/federation.ts b/src/server/api/endpoints/charts/federation.ts
index ba19aae04c33c0478234bebddbaecb6f5813a443..c774f0b891869e94ac4ef8f686f0f4e0967139c1 100644
--- a/src/server/api/endpoints/charts/federation.ts
+++ b/src/server/api/endpoints/charts/federation.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import federationChart from '../../../../chart/federation';
 
 export const meta = {
@@ -25,11 +25,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await federationChart.getChart(ps.span as any, ps.limit);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/hashtag.ts b/src/server/api/endpoints/charts/hashtag.ts
index 2ef6a0606211407a348473fb593afa081edfbf17..322708ed74e7ce85d9412765e909923b8b2c18e4 100644
--- a/src/server/api/endpoints/charts/hashtag.ts
+++ b/src/server/api/endpoints/charts/hashtag.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import hashtagChart from '../../../../chart/hashtag';
 
 export const meta = {
@@ -32,11 +32,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await hashtagChart.getChart(ps.span as any, ps.limit, ps.tag);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/network.ts b/src/server/api/endpoints/charts/network.ts
index 249504f2e11daca51dc15e1630c400a6daa9f6a9..a34eab845c3aae3fe9dfea42eb1c0b4127cd990a 100644
--- a/src/server/api/endpoints/charts/network.ts
+++ b/src/server/api/endpoints/charts/network.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import networkChart from '../../../../chart/network';
 
 export const meta = {
@@ -25,11 +25,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await networkChart.getChart(ps.span as any, ps.limit);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/notes.ts b/src/server/api/endpoints/charts/notes.ts
index 0f04a4bd9094e6f2d4707f9d716b9e3574cbd328..1795c85c8ba28b417af7d5e51ba98c8261ba0fe7 100644
--- a/src/server/api/endpoints/charts/notes.ts
+++ b/src/server/api/endpoints/charts/notes.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import notesChart from '../../../../chart/notes';
 
 export const meta = {
@@ -25,11 +25,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await notesChart.getChart(ps.span as any, ps.limit);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/user/drive.ts b/src/server/api/endpoints/charts/user/drive.ts
index beb6b5bea3ed8b694114c919197157f10c6e8184..934d38c44d029b4ac17f910ce8e29189660dc2d9 100644
--- a/src/server/api/endpoints/charts/user/drive.ts
+++ b/src/server/api/endpoints/charts/user/drive.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import perUserDriveChart from '../../../../../chart/per-user-drive';
 import ID, { transform } from '../../../../../misc/cafy-id';
 
@@ -35,11 +35,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await perUserDriveChart.getChart(ps.span as any, ps.limit, ps.userId);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/user/following.ts b/src/server/api/endpoints/charts/user/following.ts
index e0aebf4255e601ada40631417a64d462dd732b0b..9eba6d2467a37d492e15bc18dbecb0b72220229e 100644
--- a/src/server/api/endpoints/charts/user/following.ts
+++ b/src/server/api/endpoints/charts/user/following.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import perUserFollowingChart from '../../../../../chart/per-user-following';
 import ID, { transform } from '../../../../../misc/cafy-id';
 
@@ -35,11 +35,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await perUserFollowingChart.getChart(ps.span as any, ps.limit, ps.userId);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/user/notes.ts b/src/server/api/endpoints/charts/user/notes.ts
index 251de4d39958eea4ca8123e68ea23cdd710583e7..20fc49cde7d172cab8d3db28a69ca6d95d50e1e7 100644
--- a/src/server/api/endpoints/charts/user/notes.ts
+++ b/src/server/api/endpoints/charts/user/notes.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import perUserNotesChart from '../../../../../chart/per-user-notes';
 import ID, { transform } from '../../../../../misc/cafy-id';
 
@@ -35,11 +35,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await perUserNotesChart.getChart(ps.span as any, ps.limit, ps.userId);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/user/reactions.ts b/src/server/api/endpoints/charts/user/reactions.ts
index f812400709503c732e6190cc29614a4802349798..bf2204a4e460b4137fd1a53d5be2e5c68634c6eb 100644
--- a/src/server/api/endpoints/charts/user/reactions.ts
+++ b/src/server/api/endpoints/charts/user/reactions.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import perUserReactionsChart from '../../../../../chart/per-user-reactions';
 import ID, { transform } from '../../../../../misc/cafy-id';
 
@@ -35,11 +35,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await perUserReactionsChart.getChart(ps.span as any, ps.limit, ps.userId);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/charts/users.ts b/src/server/api/endpoints/charts/users.ts
index 9c23235b231e0aa1e657c0bcfdc7c4a1cbe75a32..a4a3f2f4b91d2cbd7603a3639f14e5ab95ca6401 100644
--- a/src/server/api/endpoints/charts/users.ts
+++ b/src/server/api/endpoints/charts/users.ts
@@ -1,5 +1,5 @@
 import $ from 'cafy';
-import getParams from '../../get-params';
+import define from '../../define';
 import usersChart from '../../../../chart/users';
 
 export const meta = {
@@ -25,11 +25,8 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const stats = await usersChart.getChart(ps.span as any, ps.limit);
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/drive.ts b/src/server/api/endpoints/drive.ts
index 063cd475d422b6716f350d5eaa49f6e2ffc8cb8a..43fe77138562eaf3aab04bd1bbe6d2fe5915fbc8 100644
--- a/src/server/api/endpoints/drive.ts
+++ b/src/server/api/endpoints/drive.ts
@@ -1,6 +1,6 @@
 import DriveFile from '../../../models/drive-file';
-import { ILocalUser } from '../../../models/user';
 import config from '../../../config';
+import define from '../define';
 
 export const meta = {
 	desc: {
@@ -13,7 +13,7 @@ export const meta = {
 	kind: 'drive-read'
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Calculate drive usage
 	const usage = await DriveFile
 		.aggregate([{
@@ -42,4 +42,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		capacity: 1024 * 1024 * config.localDriveCapacityMb,
 		usage: usage
 	});
-});
+}));
diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts
index ae4e2249ff3b53af435abbc81ed91f7638660486..27f101562dd0a64e8c66556381607be23b49b8fd 100644
--- a/src/server/api/endpoints/drive/files.ts
+++ b/src/server/api/endpoints/drive/files.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import DriveFile, { packMany } from '../../../../models/drive-file';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -41,13 +40,10 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
-		throw 'cannot set sinceId and untilId';
+		return rej('cannot set sinceId and untilId');
 	}
 
 	const sort = {
@@ -81,5 +77,5 @@ export default async (params: any, user: ILocalUser) => {
 			sort: sort
 		});
 
-	return await packMany(files);
-};
+	res(await packMany(files));
+}));
diff --git a/src/server/api/endpoints/drive/files/attached_notes.ts b/src/server/api/endpoints/drive/files/attached_notes.ts
index ad9a2370b188da61de7d9480f8154923f1d3218e..ec5acbd751ef0fa5149c2f522aa9d32446aa786f 100644
--- a/src/server/api/endpoints/drive/files/attached_notes.ts
+++ b/src/server/api/endpoints/drive/files/attached_notes.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFile from '../../../../../models/drive-file';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import { packMany } from '../../../../../models/note';
 
 export const meta = {
@@ -28,10 +27,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
@@ -47,4 +43,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await packMany(file.metadata.attachedNoteIds || [], user, {
 		detail: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/check_existence.ts b/src/server/api/endpoints/drive/files/check_existence.ts
index a5bdad5fb974dc513454eee5e8c4444a979495eb..d3ba4b386d0c3d397621a7c3026fad528b892d38 100644
--- a/src/server/api/endpoints/drive/files/check_existence.ts
+++ b/src/server/api/endpoints/drive/files/check_existence.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy';
 import DriveFile, { pack } from '../../../../../models/drive-file';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -23,10 +22,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const file = await DriveFile.findOne({
 		md5: ps.md5,
 		'metadata.userId': user._id,
@@ -38,4 +34,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	} else {
 		res({ file: await pack(file) });
 	}
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/create.ts b/src/server/api/endpoints/drive/files/create.ts
index 2653eba6551af2bd43025505521b6d75f8ab4efa..3c334a7c1f28eacd91197249ae9229046dc56f55 100644
--- a/src/server/api/endpoints/drive/files/create.ts
+++ b/src/server/api/endpoints/drive/files/create.ts
@@ -1,10 +1,8 @@
-import * as fs from 'fs';
 const ms = require('ms');
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import { validateFileName, pack } from '../../../../../models/drive-file';
 import create from '../../../../../services/drive/add-file';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -52,11 +50,7 @@ export const meta = {
 	}
 };
 
-export default async (file: any, params: any, user: ILocalUser): Promise<any> => {
-	if (file == null) {
-		throw 'file is required';
-	}
-
+export default define(meta, (ps, user, app, file, cleanup) => new Promise(async (res, rej) => {
 	// Get 'name' parameter
 	let name = file.originalname;
 	if (name !== undefined && name !== null) {
@@ -66,35 +60,24 @@ export default async (file: any, params: any, user: ILocalUser): Promise<any> =>
 		} else if (name === 'blob') {
 			name = null;
 		} else if (!validateFileName(name)) {
-			throw 'invalid name';
+			return rej('invalid name');
 		}
 	} else {
 		name = null;
 	}
 
-	function cleanup() {
-		fs.unlink(file.path, () => {});
-	}
-
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) {
-		cleanup();
-		throw psErr;
-	}
-
 	try {
 		// Create file
 		const driveFile = await create(user, file.path, name, null, ps.folderId, ps.force, false, null, null, ps.isSensitive);
 
 		cleanup();
 
-		// Serialize
-		return pack(driveFile);
+		res(pack(driveFile));
 	} catch (e) {
 		console.error(e);
 
 		cleanup();
 
-		throw e;
+		rej(e);
 	}
-};
+}));
diff --git a/src/server/api/endpoints/drive/files/delete.ts b/src/server/api/endpoints/drive/files/delete.ts
index af7e1926554fee17ff15c78d671c72dca175ea0c..7367c8fbb6cc81f29f13d404f341f7fa49a90e1b 100644
--- a/src/server/api/endpoints/drive/files/delete.ts
+++ b/src/server/api/endpoints/drive/files/delete.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id
 import DriveFile from '../../../../../models/drive-file';
 import del from '../../../../../services/drive/delete-file';
 import { publishDriveStream } from '../../../../../stream';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -29,10 +28,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
@@ -51,4 +47,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	publishDriveStream(user._id, 'fileDeleted', file._id);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/find.ts b/src/server/api/endpoints/drive/files/find.ts
index 0ac110c1109e4d7ad738f97b76df093e2ef0c9a3..1f9c3de1cff575321fb273eed5c237b976a94376 100644
--- a/src/server/api/endpoints/drive/files/find.ts
+++ b/src/server/api/endpoints/drive/files/find.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFile, { pack } from '../../../../../models/drive-file';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -24,10 +23,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const files = await DriveFile
 		.find({
 			filename: name,
@@ -36,4 +32,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await Promise.all(files.map(file => pack(file))));
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/show.ts b/src/server/api/endpoints/drive/files/show.ts
index ce0812c508fb8635f5630a56e81131795971582a..450a97065b30b4949f144be2dc44d28adddff1e4 100644
--- a/src/server/api/endpoints/drive/files/show.ts
+++ b/src/server/api/endpoints/drive/files/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFile, { pack } from '../../../../../models/drive-file';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
@@ -49,4 +45,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	});
 
 	res(_file);
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/update.ts b/src/server/api/endpoints/drive/files/update.ts
index 7c335e5bc6e551f435161417071f2134699a5b4b..4efec3dc2a56314f7b32612f80dcc191606407b5 100644
--- a/src/server/api/endpoints/drive/files/update.ts
+++ b/src/server/api/endpoints/drive/files/update.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id
 import DriveFolder from '../../../../../models/drive-folder';
 import DriveFile, { validateFileName, pack } from '../../../../../models/drive-file';
 import { publishDriveStream } from '../../../../../stream';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import Note from '../../../../../models/note';
 
 export const meta = {
@@ -54,10 +53,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch file
 	const file = await DriveFile
 		.findOne({
@@ -122,4 +118,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Publish fileUpdated event
 	publishDriveStream(user._id, 'fileUpdated', fileObj);
-});
+}));
diff --git a/src/server/api/endpoints/drive/files/upload_from_url.ts b/src/server/api/endpoints/drive/files/upload_from_url.ts
index 3d19725275bc81e4d61d2aa81a539620d6784bff..35309d623e65c043863faf533933de60d57fea1e 100644
--- a/src/server/api/endpoints/drive/files/upload_from_url.ts
+++ b/src/server/api/endpoints/drive/files/upload_from_url.ts
@@ -3,7 +3,7 @@ const ms = require('ms');
 import { pack } from '../../../../../models/drive-file';
 import uploadFromUrl from '../../../../../services/drive/upload-from-url';
 import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -33,9 +33,6 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser): Promise<any> => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
-	return pack(await uploadFromUrl(ps.url, user, ps.folderId));
-};
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
+	res(pack(await uploadFromUrl(ps.url, user, ps.folderId)));
+}));
diff --git a/src/server/api/endpoints/drive/folders.ts b/src/server/api/endpoints/drive/folders.ts
index 95700ee26c8e090065c778a5823bc0611d223447..3a76ecd27dad110353bbd5ed832f8d4bdf4ae022 100644
--- a/src/server/api/endpoints/drive/folders.ts
+++ b/src/server/api/endpoints/drive/folders.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import DriveFolder, { pack } from '../../../../models/drive-folder';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -37,10 +36,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -71,4 +67,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await Promise.all(folders.map(folder => pack(folder))));
-});
+}));
diff --git a/src/server/api/endpoints/drive/folders/create.ts b/src/server/api/endpoints/drive/folders/create.ts
index b51fb0264e16fd6f71ec0178f8f3193dd9e4a4b4..63c6a436d46253c3ad558d2eb6238658333fdfd3 100644
--- a/src/server/api/endpoints/drive/folders/create.ts
+++ b/src/server/api/endpoints/drive/folders/create.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
 import { publishDriveStream } from '../../../../../stream';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -37,10 +36,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// If the parent folder is specified
 	let parent = null;
 	if (ps.parentId) {
@@ -72,4 +68,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Publish folderCreated event
 	publishDriveStream(user._id, 'folderCreated', folderObj);
-});
+}));
diff --git a/src/server/api/endpoints/drive/folders/delete.ts b/src/server/api/endpoints/drive/folders/delete.ts
index 304666bdc9a62ff67f8a43c2adc023b361daf0a0..019c5eb00b16a3f1bd84e25a3f9c1b95e08bff3a 100644
--- a/src/server/api/endpoints/drive/folders/delete.ts
+++ b/src/server/api/endpoints/drive/folders/delete.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFolder from '../../../../../models/drive-folder';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 import { publishDriveStream } from '../../../../../stream';
 import DriveFile from '../../../../../models/drive-file';
 
@@ -29,10 +28,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get folder
 	const folder = await DriveFolder
 		.findOne({
@@ -59,4 +55,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	publishDriveStream(user._id, 'folderDeleted', folder._id);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/drive/folders/find.ts b/src/server/api/endpoints/drive/folders/find.ts
index 3d24d1868595e58b712b0b69ee6b0863a99c64dd..a8ce012f1059dee84c63a5dc3e40ba1c295d877e 100644
--- a/src/server/api/endpoints/drive/folders/find.ts
+++ b/src/server/api/endpoints/drive/folders/find.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFolder, { pack } from '../../../../../models/drive-folder';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -24,10 +23,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const folders = await DriveFolder
 		.find({
 			name: name,
@@ -36,4 +32,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await Promise.all(folders.map(folder => pack(folder))));
-});
+}));
diff --git a/src/server/api/endpoints/drive/folders/show.ts b/src/server/api/endpoints/drive/folders/show.ts
index b7d8f0a29bfed4cd685c0babfb859087d326f53c..49e51544b65a263a7ef9f37f412117aaf702bf56 100644
--- a/src/server/api/endpoints/drive/folders/show.ts
+++ b/src/server/api/endpoints/drive/folders/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFolder, { pack } from '../../../../../models/drive-folder';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get folder
 	const folder = await DriveFolder
 		.findOne({
@@ -46,4 +42,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await pack(folder, {
 		detail: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/drive/folders/update.ts b/src/server/api/endpoints/drive/folders/update.ts
index 53bb14bfe7201234a163f7d4a4746cc5d35172d7..f10f9c820d28ddd428d13829dd33a976421e70d7 100644
--- a/src/server/api/endpoints/drive/folders/update.ts
+++ b/src/server/api/endpoints/drive/folders/update.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import DriveFolder, { isValidFolderName, pack } from '../../../../../models/drive-folder';
 import { publishDriveStream } from '../../../../../stream';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -45,10 +44,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch folder
 	const folder = await DriveFolder
 		.findOne({
@@ -122,4 +118,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Publish folderUpdated event
 	publishDriveStream(user._id, 'folderUpdated', folderObj);
-});
+}));
diff --git a/src/server/api/endpoints/drive/stream.ts b/src/server/api/endpoints/drive/stream.ts
index ecf405fe64b3db808b5242cbde398550f6c0acff..804ecf50d96c52a634f9aaeacf0de08a4c88ebda 100644
--- a/src/server/api/endpoints/drive/stream.ts
+++ b/src/server/api/endpoints/drive/stream.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import DriveFile, { packMany } from '../../../../models/drive-file';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -30,10 +29,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -70,4 +66,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await packMany(files));
-});
+}));
diff --git a/src/server/api/endpoints/following/create.ts b/src/server/api/endpoints/following/create.ts
index 7795bbcc612914db0fcc2a4c5b3c99fa89723558..f8267768923284bddba5f5ab19770430d63b8c2c 100644
--- a/src/server/api/endpoints/following/create.ts
+++ b/src/server/api/endpoints/following/create.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 const ms = require('ms');
-import User, { pack, ILocalUser } from '../../../../models/user';
+import User, { pack } from '../../../../models/user';
 import Following from '../../../../models/following';
 import create from '../../../../services/following/create';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -34,10 +34,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// 自分自身
@@ -78,4 +75,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Send response
 	res(await pack(followee._id, user));
-});
+}));
diff --git a/src/server/api/endpoints/following/delete.ts b/src/server/api/endpoints/following/delete.ts
index ae0edd34ee3455b649476fb91c1158bbda463076..92a50ce7223f9611af9566222aa4fadf49ebb2c0 100644
--- a/src/server/api/endpoints/following/delete.ts
+++ b/src/server/api/endpoints/following/delete.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 const ms = require('ms');
-import User, { pack, ILocalUser } from '../../../../models/user';
+import User, { pack } from '../../../../models/user';
 import Following from '../../../../models/following';
 import deleteFollowing from '../../../../services/following/delete';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -34,10 +34,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// Check if the followee is yourself
@@ -74,4 +71,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Send response
 	res(await pack(followee._id, user));
-});
+}));
diff --git a/src/server/api/endpoints/following/requests/accept.ts b/src/server/api/endpoints/following/requests/accept.ts
index 1172f463d6bb539a1403b913c2235ee015ca7768..36c3694eeded9112557d17c3840545cf7b7a6eed 100644
--- a/src/server/api/endpoints/following/requests/accept.ts
+++ b/src/server/api/endpoints/following/requests/accept.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import acceptFollowRequest from '../../../../../services/following/requests/accept';
-import User, { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import User from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch follower
 	const follower = await User.findOne({
 		_id: ps.userId
@@ -37,4 +34,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	await acceptFollowRequest(user, follower);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/following/requests/cancel.ts b/src/server/api/endpoints/following/requests/cancel.ts
index 77bfcfe15e6a3ff7ac67d4dcc666a0c237fc9142..bfb7d0713cf09755d97af310860f95952e89ecf7 100644
--- a/src/server/api/endpoints/following/requests/cancel.ts
+++ b/src/server/api/endpoints/following/requests/cancel.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import cancelFollowRequest from '../../../../../services/following/requests/cancel';
-import User, { pack, ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import User, { pack } from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch followee
 	const followee = await User.findOne({
 		_id: ps.userId
@@ -41,4 +38,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	}
 
 	res(await pack(followee._id, user));
-});
+}));
diff --git a/src/server/api/endpoints/following/requests/list.ts b/src/server/api/endpoints/following/requests/list.ts
index 6d42d06db2c70a170539e62cc045ab28ab93216e..c561ea066c0e0c702bafe477348a821f9dcf1774 100644
--- a/src/server/api/endpoints/following/requests/list.ts
+++ b/src/server/api/endpoints/following/requests/list.ts
@@ -1,6 +1,6 @@
 //import $ from 'cafy'; import ID, { transform } from '../../../../../cafy-id';
 import FollowRequest, { pack } from '../../../../../models/follow-request';
-import { ILocalUser } from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -13,11 +13,11 @@ export const meta = {
 	kind: 'following-read'
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const reqs = await FollowRequest.find({
 		followeeId: user._id
 	});
 
 	// Send response
 	res(await Promise.all(reqs.map(req => pack(req))));
-});
+}));
diff --git a/src/server/api/endpoints/following/requests/reject.ts b/src/server/api/endpoints/following/requests/reject.ts
index 45ebb7807bf334a070279af887100f024363cc5f..bd0b3bba2270a89b53aae230e5ddd9f08a1adc51 100644
--- a/src/server/api/endpoints/following/requests/reject.ts
+++ b/src/server/api/endpoints/following/requests/reject.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import rejectFollowRequest from '../../../../../services/following/requests/reject';
-import User, { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import User from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch follower
 	const follower = await User.findOne({
 		_id: ps.userId
@@ -37,4 +34,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	await rejectFollowRequest(user, follower);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/following/stalk.ts b/src/server/api/endpoints/following/stalk.ts
index 434bc52b59836cfa59323422e90bea768216b944..1fef9a429a867d02f13096256207dfeb8951e2f2 100644
--- a/src/server/api/endpoints/following/stalk.ts
+++ b/src/server/api/endpoints/following/stalk.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Following from '../../../../models/following';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +20,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// Fetch following
@@ -47,4 +43,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res();
 
 	// TODO: イベント
-});
+}));
diff --git a/src/server/api/endpoints/following/unstalk.ts b/src/server/api/endpoints/following/unstalk.ts
index 00e91357ec50b748fc6998e3e88e13d530188a04..66e99bed5872114c5101ba9f585dc9cfac281614 100644
--- a/src/server/api/endpoints/following/unstalk.ts
+++ b/src/server/api/endpoints/following/unstalk.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Following from '../../../../models/following';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +20,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// Fetch following
@@ -47,4 +43,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res();
 
 	// TODO: イベント
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/games.ts b/src/server/api/endpoints/games/reversi/games.ts
index 9c7a7c4d7498bafe9c52648c482d8c788a992626..2bebe36ef82d2804733d8aa201ccbf0fa6e22c9c 100644
--- a/src/server/api/endpoints/games/reversi/games.ts
+++ b/src/server/api/endpoints/games/reversi/games.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import ReversiGame, { pack } from '../../../../../models/games/reversi/game';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	params: {
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -72,4 +68,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(Promise.all(games.map(async (g) => await pack(g, user, {
 		detail: false
 	}))));
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/games/show.ts b/src/server/api/endpoints/games/reversi/games/show.ts
index a2c84ae82d920ca8123b62cb8bce67b6fd68e321..c747202354fb495a37f445459237f138ca10c0eb 100644
--- a/src/server/api/endpoints/games/reversi/games/show.ts
+++ b/src/server/api/endpoints/games/reversi/games/show.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../../misc/cafy-id';
 import ReversiGame, { pack } from '../../../../../../models/games/reversi/game';
 import Reversi from '../../../../../../games/reversi/core';
-import { ILocalUser } from '../../../../../../models/user';
-import getParams from '../../../../get-params';
+import define from '../../../../define';
 
 export const meta = {
 	params: {
@@ -13,10 +12,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const game = await ReversiGame.findOne({ _id: ps.gameId });
 
 	if (game == null) {
@@ -39,4 +35,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		board: o.board,
 		turn: o.turn
 	}, packed));
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/games/surrender.ts b/src/server/api/endpoints/games/reversi/games/surrender.ts
index 2860c154fed7e34119a4e273694feeead689465a..aab88da6648024592966602bf24d64c7338a41e8 100644
--- a/src/server/api/endpoints/games/reversi/games/surrender.ts
+++ b/src/server/api/endpoints/games/reversi/games/surrender.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../../misc/cafy-id';
 import ReversiGame, { pack } from '../../../../../../models/games/reversi/game';
-import { ILocalUser } from '../../../../../../models/user';
-import getParams from '../../../../get-params';
 import { publishReversiGameStream } from '../../../../../../stream';
+import define from '../../../../define';
 
 export const meta = {
 	desc: {
@@ -22,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const game = await ReversiGame.findOne({ _id: ps.gameId });
 
 	if (game == null) {
@@ -58,4 +54,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/invitations.ts b/src/server/api/endpoints/games/reversi/invitations.ts
index 39622827597bed45f52672f326f57a3991993869..d808ff2e782123e3836b5caee980b12a508e3fde 100644
--- a/src/server/api/endpoints/games/reversi/invitations.ts
+++ b/src/server/api/endpoints/games/reversi/invitations.ts
@@ -1,11 +1,11 @@
 import Matching, { pack as packMatching } from '../../../../../models/games/reversi/matching';
-import { ILocalUser } from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Find session
 	const invitations = await Matching.find({
 		childId: user._id
@@ -17,4 +17,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Reponse
 	res(Promise.all(invitations.map(async (i) => await packMatching(i, user))));
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/match.ts b/src/server/api/endpoints/games/reversi/match.ts
index f43650aeeb482edc1f90534c23ae4bd9869577df..e0f9c20cbb52e648b0073f3c9fbde94181fb7f76 100644
--- a/src/server/api/endpoints/games/reversi/match.ts
+++ b/src/server/api/endpoints/games/reversi/match.ts
@@ -1,10 +1,10 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import Matching, { pack as packMatching } from '../../../../../models/games/reversi/matching';
 import ReversiGame, { pack as packGame } from '../../../../../models/games/reversi/game';
-import User, { ILocalUser } from '../../../../../models/user';
+import User from '../../../../../models/user';
 import { publishMainStream, publishReversiStream } from '../../../../../stream';
 import { eighteight } from '../../../../../games/reversi/maps';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -17,10 +17,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Myself
 	if (ps.userId.equals(user._id)) {
 		return rej('invalid userId param');
@@ -103,4 +100,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 		publishMainStream(child._id, 'reversiInvited', packed);
 	}
-});
+}));
diff --git a/src/server/api/endpoints/games/reversi/match/cancel.ts b/src/server/api/endpoints/games/reversi/match/cancel.ts
index d5c186409c8351e9cfeb0cc6683ab0688d0be743..ac51e416ed1653675b4efb5d2a898bc561bfd0f7 100644
--- a/src/server/api/endpoints/games/reversi/match/cancel.ts
+++ b/src/server/api/endpoints/games/reversi/match/cancel.ts
@@ -1,14 +1,14 @@
 import Matching from '../../../../../../models/games/reversi/matching';
-import { ILocalUser } from '../../../../../../models/user';
+import define from '../../../../define';
 
 export const meta = {
 	requireCredential: true
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	await Matching.remove({
 		parentId: user._id
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/hashtags/search.ts b/src/server/api/endpoints/hashtags/search.ts
index 35ae2a83b315047bbead2a4e6a72a0ca1ce6f3b4..4d753808d4f1b4c30355af21104262910f6059d5 100644
--- a/src/server/api/endpoints/hashtags/search.ts
+++ b/src/server/api/endpoints/hashtags/search.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import Hashtag from '../../../../models/hashtag';
-import getParams from '../../get-params';
+import define from '../../define';
 const escapeRegexp = require('escape-regexp');
 
 export const meta = {
@@ -36,10 +36,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	const hashtags = await Hashtag
 		.find({
 			tag: new RegExp('^' + escapeRegexp(ps.query.toLowerCase()))
@@ -52,4 +49,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 		});
 
 	res(hashtags.map(tag => tag.tag));
-});
+}));
diff --git a/src/server/api/endpoints/hashtags/trend.ts b/src/server/api/endpoints/hashtags/trend.ts
index 0ec6a4ffec1d2504ad36803f76d68439d5adcad3..02d398a6837d8c02dbe4ba4ef1f6c7310d78732f 100644
--- a/src/server/api/endpoints/hashtags/trend.ts
+++ b/src/server/api/endpoints/hashtags/trend.ts
@@ -1,6 +1,7 @@
 import Note from '../../../../models/note';
 import { erase } from '../../../../prelude/array';
 import Meta from '../../../../models/meta';
+import define from '../../define';
 
 /*
 トレンドに載るためには「『直近a分間のユニーク投稿数が今からa分前~今からb分前の間のユニーク投稿数のn倍以上』のハッシュタグの上位5位以内に入る」ことが必要
@@ -14,10 +15,11 @@ const requiredUsers = 3; // 最低何人がそのタグを投稿している必
 
 const max = 5;
 
-/**
- * Get trends of hashtags
- */
-export default () => new Promise(async (res, rej) => {
+export const meta = {
+	requireCredential: false,
+};
+
+export default define(meta, () => new Promise(async (res, rej) => {
 	const meta = await Meta.findOne({});
 	const hidedTags = meta ? (meta.hidedTags || []).map(t => t.toLowerCase()) : [];
 
@@ -143,4 +145,4 @@ export default () => new Promise(async (res, rej) => {
 	}));
 
 	res(stats);
-});
+}));
diff --git a/src/server/api/endpoints/i.ts b/src/server/api/endpoints/i.ts
index 1c488d94c69c0ac73fb90392a7d7aa3fcdefff12..aea47ad7958439b4057b749357865d93e867e642 100644
--- a/src/server/api/endpoints/i.ts
+++ b/src/server/api/endpoints/i.ts
@@ -1,5 +1,5 @@
-import User, { pack, ILocalUser } from '../../../models/user';
-import { IApp } from '../../../models/app';
+import User, { pack } from '../../../models/user';
+import define from '../define';
 
 export const meta = {
 	stability: 'stable',
@@ -18,7 +18,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
 	const isSecure = user != null && app == null;
 
 	// Serialize
@@ -34,4 +34,4 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
 			lastUsedAt: new Date()
 		}
 	});
-});
+}));
diff --git a/src/server/api/endpoints/i/2fa/done.ts b/src/server/api/endpoints/i/2fa/done.ts
index 40b45a3d0b0f73ce08ccd65f16bdeac7cc5fede8..2ee0c8886ee6abef359eb4cb7672ea0012a9409a 100644
--- a/src/server/api/endpoints/i/2fa/done.ts
+++ b/src/server/api/endpoints/i/2fa/done.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as speakeasy from 'speakeasy';
-import User, { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import User from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -15,10 +15,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const _token = ps.token.replace(/\s/g, '');
 
 	if (user.twoFactorTempSecret == null) {
@@ -43,4 +40,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/i/2fa/register.ts b/src/server/api/endpoints/i/2fa/register.ts
index 4d6b05b787244ba2b24b662b4e7fc1f60fcebe41..38e3ca7806efecc1d0df92f965e2061b7c6d1eb6 100644
--- a/src/server/api/endpoints/i/2fa/register.ts
+++ b/src/server/api/endpoints/i/2fa/register.ts
@@ -2,9 +2,9 @@ import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
 import * as speakeasy from 'speakeasy';
 import * as QRCode from 'qrcode';
-import User, { ILocalUser } from '../../../../../models/user';
+import User from '../../../../../models/user';
 import config from '../../../../../config';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -18,10 +18,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Compare password
 	const same = await bcrypt.compare(ps.password, user.password);
 
@@ -54,4 +51,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 			issuer: config.host
 		});
 	});
-});
+}));
diff --git a/src/server/api/endpoints/i/2fa/unregister.ts b/src/server/api/endpoints/i/2fa/unregister.ts
index e3a1bd43de3b9330121dfecfdcd81d49d4b2c792..2cb48d93cd54e8139d572429b2b970825ef15b77 100644
--- a/src/server/api/endpoints/i/2fa/unregister.ts
+++ b/src/server/api/endpoints/i/2fa/unregister.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
-import User, { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import User from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -15,10 +15,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Compare password
 	const same = await bcrypt.compare(ps.password, user.password);
 
@@ -34,4 +31,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/i/authorized_apps.ts b/src/server/api/endpoints/i/authorized_apps.ts
index 09bcd2dcb630e3659e42494689ccd60ee8b31b6f..c4b992b52f503006507ed488ed46b1cc3de5e23e 100644
--- a/src/server/api/endpoints/i/authorized_apps.ts
+++ b/src/server/api/endpoints/i/authorized_apps.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import AccessToken from '../../../../models/access-token';
 import { pack } from '../../../../models/app';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get tokens
 	const tokens = await AccessToken
 		.find({
@@ -46,4 +42,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await Promise.all(tokens.map(token => pack(token.appId, user, {
 		detail: true
 	}))));
-});
+}));
diff --git a/src/server/api/endpoints/i/change_password.ts b/src/server/api/endpoints/i/change_password.ts
index 818637e22436c3d9959dca22e458d6b181a281d5..a2cfc6f70e341575b7647483be8787b638cef6e0 100644
--- a/src/server/api/endpoints/i/change_password.ts
+++ b/src/server/api/endpoints/i/change_password.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
-import User, { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import User from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Compare password
 	const same = await bcrypt.compare(ps.currentPassword, user.password);
 
@@ -41,4 +38,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/i/favorites.ts b/src/server/api/endpoints/i/favorites.ts
index 847ac64d9a8745abdfb3bfe3276a7c1ca179cd39..67a3638885ed59be01daca38109868ead53cf227 100644
--- a/src/server/api/endpoints/i/favorites.ts
+++ b/src/server/api/endpoints/i/favorites.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Favorite, { packMany } from '../../../../models/favorite';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -31,10 +30,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -67,4 +63,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await packMany(favorites, user));
-});
+}));
diff --git a/src/server/api/endpoints/i/notifications.ts b/src/server/api/endpoints/i/notifications.ts
index d16ba63bdc47d35e0edb043f2330317e41ba2029..b1ddd40d13f983165cf06744c7762f034464edc3 100644
--- a/src/server/api/endpoints/i/notifications.ts
+++ b/src/server/api/endpoints/i/notifications.ts
@@ -4,8 +4,7 @@ import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/notification';
 import { getFriendIds } from '../../common/get-friends';
 import read from '../../common/read-notification';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -45,10 +44,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -105,4 +101,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	if (notifications.length > 0 && ps.markAsRead) {
 		read(user._id, notifications);
 	}
-});
+}));
diff --git a/src/server/api/endpoints/i/pin.ts b/src/server/api/endpoints/i/pin.ts
index 4341906a5779c03ab906d272ac12a16c3f9b2f0e..ab8d8a185312dd22ac25324d128df0cea0f219ce 100644
--- a/src/server/api/endpoints/i/pin.ts
+++ b/src/server/api/endpoints/i/pin.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import { ILocalUser } from '../../../../models/user';
 import { pack } from '../../../../models/user';
 import { addPinned } from '../../../../services/i/pin';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Processing
 	try {
 		await addPinned(user, ps.noteId);
@@ -45,4 +41,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 
 	// Send response
 	res(iObj);
-});
+}));
diff --git a/src/server/api/endpoints/i/read_all_unread_notes.ts b/src/server/api/endpoints/i/read_all_unread_notes.ts
index 6a4f72ea29185e87d79a825634022150067e3783..7d63de4e19620a36c2035c19e95b8ce07f619e30 100644
--- a/src/server/api/endpoints/i/read_all_unread_notes.ts
+++ b/src/server/api/endpoints/i/read_all_unread_notes.ts
@@ -1,6 +1,7 @@
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
 import NoteUnread from '../../../../models/note-unread';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -16,7 +17,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Remove documents
 	await NoteUnread.remove({
 		userId: user._id
@@ -34,4 +35,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	publishMainStream(user._id, 'readAllUnreadSpecifiedNotes');
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/i/regenerate_token.ts b/src/server/api/endpoints/i/regenerate_token.ts
index 81997362fc9188e462d0fe55e386a2fab45b3413..5dfc3cd6644f450560f867101576f2749f633cb5 100644
--- a/src/server/api/endpoints/i/regenerate_token.ts
+++ b/src/server/api/endpoints/i/regenerate_token.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy';
 import * as bcrypt from 'bcryptjs';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
 import generateUserToken from '../../common/generate-native-user-token';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -17,10 +17,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Compare password
 	const same = await bcrypt.compare(ps.password, user.password);
 
@@ -41,4 +38,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 
 	// Publish event
 	publishMainStream(user._id, 'myTokenRegenerated');
-});
+}));
diff --git a/src/server/api/endpoints/i/signin_history.ts b/src/server/api/endpoints/i/signin_history.ts
index df1cd34c8c911b4d221af16b2597a6a5a86b8252..acf9349cd2920db31440a3a358eb41c6ef2b682e 100644
--- a/src/server/api/endpoints/i/signin_history.ts
+++ b/src/server/api/endpoints/i/signin_history.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Signin, { pack } from '../../../../models/signin';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -26,10 +25,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -62,4 +58,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Serialize
 	res(await Promise.all(history.map(record => pack(record))));
-});
+}));
diff --git a/src/server/api/endpoints/i/unpin.ts b/src/server/api/endpoints/i/unpin.ts
index 26ff8ccda10560b1a496f2c9c5f3e1c50aec2dcd..27342fb43cee14491c22b995b6a815e13a45a24b 100644
--- a/src/server/api/endpoints/i/unpin.ts
+++ b/src/server/api/endpoints/i/unpin.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import { ILocalUser } from '../../../../models/user';
 import { pack } from '../../../../models/user';
 import { removePinned } from '../../../../services/i/pin';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -27,10 +26,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Processing
 	try {
 		await removePinned(user, ps.noteId);
@@ -45,4 +41,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 
 	// Send response
 	res(iObj);
-});
+}));
diff --git a/src/server/api/endpoints/i/update.ts b/src/server/api/endpoints/i/update.ts
index 93d4448092a1f270a2461d8891e4f45b9a49068e..7a1624830504ebbcd79ca4125eabd07ea5b0ec17 100644
--- a/src/server/api/endpoints/i/update.ts
+++ b/src/server/api/endpoints/i/update.ts
@@ -5,7 +5,7 @@ import DriveFile from '../../../../models/drive-file';
 import acceptAllFollowRequests from '../../../../services/following/requests/accept-all';
 import { IApp } from '../../../../models/app';
 import { publishToFollowers } from '../../../../services/i/update';
-import getParams from '../../get-params';
+import define from '../../define';
 import getDriveFileUrl from '../../../../misc/get-drive-file-url';
 
 export const meta = {
@@ -115,10 +115,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
 	const isSecure = user != null && app == null;
 
 	const updates = {} as any;
@@ -209,4 +206,4 @@ export default async (params: any, user: ILocalUser, app: IApp) => new Promise(a
 
 	// フォロワーにUpdateを配信
 	publishToFollowers(user._id);
-});
+}));
diff --git a/src/server/api/endpoints/i/update_client_setting.ts b/src/server/api/endpoints/i/update_client_setting.ts
index a1631b1d95cf84aa765574a66133457a2c190aac..03eb23a5a2cd8cb9d5d16d09d244c5f5573f7faa 100644
--- a/src/server/api/endpoints/i/update_client_setting.ts
+++ b/src/server/api/endpoints/i/update_client_setting.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const x: any = {};
 	x[`clientSettings.${name}`] = ps.value;
 
@@ -37,4 +34,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 		key: name,
 		value: ps.value
 	});
-});
+}));
diff --git a/src/server/api/endpoints/i/update_home.ts b/src/server/api/endpoints/i/update_home.ts
index eadd0290aba008189ed37efb261d7a45fb7a7089..f472600ee06a083d18c24078a2ce073541ef2e0b 100644
--- a/src/server/api/endpoints/i/update_home.ts
+++ b/src/server/api/endpoints/i/update_home.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -20,10 +20,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	await User.update(user._id, {
 		$set: {
 			'clientSettings.home': ps.home
@@ -33,4 +30,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	res();
 
 	publishMainStream(user._id, 'homeUpdated', ps.home);
-});
+}));
diff --git a/src/server/api/endpoints/i/update_mobile_home.ts b/src/server/api/endpoints/i/update_mobile_home.ts
index c886574f23fc27f0ac1be1f91db1125affa9d753..792c4b7877c67b37d585db5a1615a095753845e9 100644
--- a/src/server/api/endpoints/i/update_mobile_home.ts
+++ b/src/server/api/endpoints/i/update_mobile_home.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	await User.update(user._id, {
 		$set: {
 			'clientSettings.mobileHome': ps.home
@@ -32,4 +29,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	res();
 
 	publishMainStream(user._id, 'mobileHomeUpdated', ps.home);
-});
+}));
diff --git a/src/server/api/endpoints/i/update_widget.ts b/src/server/api/endpoints/i/update_widget.ts
index 947a29074c960083cae4b1cbe6c3e860df2400a8..90fe8fbe23ce598186c2211f9b16862a00d4a774 100644
--- a/src/server/api/endpoints/i/update_widget.ts
+++ b/src/server/api/endpoints/i/update_widget.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { publishMainStream } from '../../../../stream';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	if (ps.id == null && ps.data == null) return rej('you need to set id and data params if home param unset');
 
 	let widget;
@@ -88,4 +85,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 	} else {
 		rej('widget not found');
 	}
-});
+}));
diff --git a/src/server/api/endpoints/messaging/history.ts b/src/server/api/endpoints/messaging/history.ts
index 078af21f27e532dc3df1cd8faf1b61d86602b8b4..c026e5dd91602dda720881e7bf9b8305af9f25d1 100644
--- a/src/server/api/endpoints/messaging/history.ts
+++ b/src/server/api/endpoints/messaging/history.ts
@@ -2,8 +2,7 @@ import $ from 'cafy';
 import History from '../../../../models/messaging-history';
 import Mute from '../../../../models/mute';
 import { pack } from '../../../../models/messaging-message';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -23,10 +22,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const mute = await Mute.find({
 		muterId: user._id,
 		deletedAt: { $exists: false }
@@ -47,4 +43,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await Promise.all(history.map(h => pack(h.messageId, user))));
-});
+}));
diff --git a/src/server/api/endpoints/messaging/messages.ts b/src/server/api/endpoints/messaging/messages.ts
index 43d96e2ee4fca3891e36ebe8a80c51f37d857651..50a5eb00d81447368c79c477887a5fe08b1a6c8a 100644
--- a/src/server/api/endpoints/messaging/messages.ts
+++ b/src/server/api/endpoints/messaging/messages.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Message from '../../../../models/messaging-message';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import { pack } from '../../../../models/messaging-message';
 import read from '../../common/read-messaging-message';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -43,10 +43,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -108,4 +105,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	if (ps.markAsRead) {
 		read(user._id, recipient._id, messages);
 	}
-});
+}));
diff --git a/src/server/api/endpoints/messaging/messages/create.ts b/src/server/api/endpoints/messaging/messages/create.ts
index ff44e192d1f850b25854a070ee27a963b5ed74d5..bcd4d6b63c209a83951f07503c9bfecd2594f269 100644
--- a/src/server/api/endpoints/messaging/messages/create.ts
+++ b/src/server/api/endpoints/messaging/messages/create.ts
@@ -2,14 +2,14 @@ import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id
 import Message from '../../../../../models/messaging-message';
 import { isValidText } from '../../../../../models/messaging-message';
 import History from '../../../../../models/messaging-history';
-import User, { ILocalUser } from '../../../../../models/user';
+import User from '../../../../../models/user';
 import Mute from '../../../../../models/mute';
 import DriveFile from '../../../../../models/drive-file';
 import { pack } from '../../../../../models/messaging-message';
 import { publishMainStream } from '../../../../../stream';
 import { publishMessagingStream, publishMessagingIndexStream } from '../../../../../stream';
 import pushSw from '../../../../../push-sw';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -38,10 +38,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Myself
 	if (ps.userId.equals(user._id)) {
 		return rej('cannot send message to myself');
@@ -155,4 +152,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	}, {
 		upsert: true
 	});
-});
+}));
diff --git a/src/server/api/endpoints/messaging/messages/read.ts b/src/server/api/endpoints/messaging/messages/read.ts
index 122034fdf064248ea5c8d89915b25afce714a64c..eb1799cfc611fd81a52dad52634f2e5df579976e 100644
--- a/src/server/api/endpoints/messaging/messages/read.ts
+++ b/src/server/api/endpoints/messaging/messages/read.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import Message from '../../../../../models/messaging-message';
-import { ILocalUser } from '../../../../../models/user';
 import read from '../../../common/read-messaging-message';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -26,10 +25,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const message = await Message.findOne({
 		_id: ps.messageId,
 		recipientId: user._id
@@ -42,4 +38,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	read(user._id, message.userId, message);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/meta.ts b/src/server/api/endpoints/meta.ts
index e33023b07bb34a2ab6737cdac487339c6ee50c78..be42c070ec9fa25a27ed3799d71fe8230a51db1f 100644
--- a/src/server/api/endpoints/meta.ts
+++ b/src/server/api/endpoints/meta.ts
@@ -2,9 +2,8 @@ import $ from 'cafy';
 import * as os from 'os';
 import config from '../../../config';
 import Meta from '../../../models/meta';
-import { ILocalUser } from '../../../models/user';
 import Emoji from '../../../models/emoji';
-import getParams from '../get-params';
+import define from '../define';
 
 const pkg = require('../../../../package.json');
 const client = require('../../../../built/client/meta.json');
@@ -27,10 +26,7 @@ export const meta = {
 	},
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	const met: any = (await Meta.findOne()) || {};
 
 	const emojis = await Emoji.find({ host: null });
@@ -76,4 +72,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 			userRecommendation: config.user_recommendation ? config.user_recommendation : {}
 		} : undefined
 	});
-});
+}));
diff --git a/src/server/api/endpoints/mute/create.ts b/src/server/api/endpoints/mute/create.ts
index 442d3f51d8be3a1e4770362f2d7c4e2befe781c1..f3bb3da14f93bcd014495eb91e544b967ad0d374 100644
--- a/src/server/api/endpoints/mute/create.ts
+++ b/src/server/api/endpoints/mute/create.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import Mute from '../../../../models/mute';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const muter = user;
 
 	// 自分自身
@@ -64,4 +61,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/mute/delete.ts b/src/server/api/endpoints/mute/delete.ts
index c1d4f354251584a8019dd43c7e700a405f153b4a..68de0feb28176382558656fb9086973595ec17f2 100644
--- a/src/server/api/endpoints/mute/delete.ts
+++ b/src/server/api/endpoints/mute/delete.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import Mute from '../../../../models/mute';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const muter = user;
 
 	// Check if the mutee is yourself
@@ -62,4 +59,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/mute/list.ts b/src/server/api/endpoints/mute/list.ts
index e33e7097738b8bb57d9be584ba2e97f10ef53742..c337ba4ec97225b2727be7cde5402b814c5f2c46 100644
--- a/src/server/api/endpoints/mute/list.ts
+++ b/src/server/api/endpoints/mute/list.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Mute, { packMany } from '../../../../models/mute';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -31,10 +30,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -66,4 +62,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		});
 
 	res(await packMany(mutes, me));
-});
+}));
diff --git a/src/server/api/endpoints/my/apps.ts b/src/server/api/endpoints/my/apps.ts
index 0b051f600c2e38a0c2b4ce6ab5a960e440d4aa92..646ffcc263cfe90ebf5aca40d4dbb66759748e48 100644
--- a/src/server/api/endpoints/my/apps.ts
+++ b/src/server/api/endpoints/my/apps.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy';
 import App, { pack } from '../../../../models/app';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -24,10 +23,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const query = {
 		userId: user._id
 	};
@@ -46,4 +42,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await Promise.all(apps.map(app => pack(app, user, {
 		detail: true
 	}))));
-});
+}));
diff --git a/src/server/api/endpoints/notes.ts b/src/server/api/endpoints/notes.ts
index 83776c59d0143d40c026aab7b6c48352a004dc4b..5edc56165eaaf9850fa48ceb678c695e5b51b5b1 100644
--- a/src/server/api/endpoints/notes.ts
+++ b/src/server/api/endpoints/notes.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../misc/cafy-id';
 import Note, { packMany } from '../../../models/note';
-import getParams from '../get-params';
+import define from '../define';
 
 export const meta = {
 	desc: {
@@ -67,10 +67,7 @@ export const meta = {
 	}
 };
 
-export default (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -130,4 +127,4 @@ export default (params: any) => new Promise(async (res, rej) => {
 
 	// Serialize
 	res(await packMany(notes));
-});
+}));
diff --git a/src/server/api/endpoints/notes/conversation.ts b/src/server/api/endpoints/notes/conversation.ts
index c7be6d6e3feece93f14896a2f35e0cba0d517c8e..7703ef7d2e49781712f923b73ec680bbe5e768c8 100644
--- a/src/server/api/endpoints/notes/conversation.ts
+++ b/src/server/api/endpoints/notes/conversation.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note, { packMany, INote } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -29,10 +28,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Lookup note
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -67,4 +63,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	}
 
 	res(await packMany(conversation, user));
-});
+}));
diff --git a/src/server/api/endpoints/notes/create.ts b/src/server/api/endpoints/notes/create.ts
index 9eff8c27bf43b868d60a71752a3b7f3f6c127994..8a8813daba31416dc1aa26e0d5a5f1f2dc654d29 100644
--- a/src/server/api/endpoints/notes/create.ts
+++ b/src/server/api/endpoints/notes/create.ts
@@ -1,11 +1,10 @@
 import $ from 'cafy'; import ID, { transform, transformMany } from '../../../../misc/cafy-id';
 const ms = require('ms');
 import Note, { INote, isValidText, isValidCw, pack } from '../../../../models/note';
-import User, { ILocalUser, IUser } from '../../../../models/user';
+import User, { IUser } from '../../../../models/user';
 import DriveFile, { IDriveFile } from '../../../../models/drive-file';
 import create from '../../../../services/note/create';
-import { IApp } from '../../../../models/app';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -139,10 +138,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user, app) => new Promise(async (res, rej) => {
 	let visibleUsers: IUser[] = [];
 	if (ps.visibleUserIds) {
 		visibleUsers = await Promise.all(ps.visibleUserIds.map(id => User.findOne({
@@ -229,4 +225,4 @@ export default (params: any, user: ILocalUser, app: IApp) => new Promise(async (
 	res({
 		createdNote: noteObj
 	});
-});
+}));
diff --git a/src/server/api/endpoints/notes/delete.ts b/src/server/api/endpoints/notes/delete.ts
index 580cb344e1ea3cc86ba3e6810062ce1ec7b351f7..a8f22ad405fe7637e4a83d3896749b2b11582486 100644
--- a/src/server/api/endpoints/notes/delete.ts
+++ b/src/server/api/endpoints/notes/delete.ts
@@ -1,8 +1,8 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
 import deleteNote from '../../../../services/note/delete';
-import User, { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import User from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -28,10 +28,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch note
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -48,4 +45,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	await deleteNote(await User.findOne({ _id: note.userId }), note);
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/notes/favorites/create.ts b/src/server/api/endpoints/notes/favorites/create.ts
index e489c77761677e751c20e3440a6fb9cd84cb984b..a50b5002c24cd4d33918d1ed050bfe67ee7b7fdf 100644
--- a/src/server/api/endpoints/notes/favorites/create.ts
+++ b/src/server/api/endpoints/notes/favorites/create.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import Favorite from '../../../../../models/favorite';
 import Note from '../../../../../models/note';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -28,10 +27,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get favoritee
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -60,4 +56,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Send response
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/notes/favorites/delete.ts b/src/server/api/endpoints/notes/favorites/delete.ts
index ac1b35d194efd8a178d4c46a6d026aaa7551f8f9..0aad61fedd0f703c155f1262a809ce1fc755f64e 100644
--- a/src/server/api/endpoints/notes/favorites/delete.ts
+++ b/src/server/api/endpoints/notes/favorites/delete.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import Favorite from '../../../../../models/favorite';
 import Note from '../../../../../models/note';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -28,10 +27,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get favoritee
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -58,4 +54,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Send response
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/notes/featured.ts b/src/server/api/endpoints/notes/featured.ts
index c031308824c940765363d04884c89cb5ff776c66..823137ac21431179ed75fcfa4987541852791145 100644
--- a/src/server/api/endpoints/notes/featured.ts
+++ b/src/server/api/endpoints/notes/featured.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import Note from '../../../../models/note';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -23,10 +22,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const day = 1000 * 60 * 60 * 24;
 
 	const notes = await Note
@@ -46,5 +42,5 @@ export default async (params: any, user: ILocalUser) => {
 			}
 		});
 
-	return await packMany(notes, user);
-};
+	res(await packMany(notes, user));
+}));
diff --git a/src/server/api/endpoints/notes/global-timeline.ts b/src/server/api/endpoints/notes/global-timeline.ts
index fa7a76f12ebe47765ffa4def16563c96320a8746..b7f765f27d1c46388f6281630db5c31748af8741 100644
--- a/src/server/api/endpoints/notes/global-timeline.ts
+++ b/src/server/api/endpoints/notes/global-timeline.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
 import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 import { countIf } from '../../../../prelude/array';
 
 export const meta = {
@@ -51,13 +50,10 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
-		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
+		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
 	}
 
 	// ミュートしているユーザーを取得
@@ -120,13 +116,11 @@ export default async (params: any, user: ILocalUser) => {
 	}
 	//#endregion
 
-	// Issue query
 	const timeline = await Note
 		.find(query, {
 			limit: ps.limit,
 			sort: sort
 		});
 
-	// Serialize
-	return await packMany(timeline, user);
-};
+	res(await packMany(timeline, user));
+}));
diff --git a/src/server/api/endpoints/notes/hybrid-timeline.ts b/src/server/api/endpoints/notes/hybrid-timeline.ts
index 000814482390cbd1e1ac5ecd3e40a0ffad59f25a..4af182cb5cfb6567f3341b9d4b22ba892dec47f3 100644
--- a/src/server/api/endpoints/notes/hybrid-timeline.ts
+++ b/src/server/api/endpoints/notes/hybrid-timeline.ts
@@ -3,8 +3,7 @@ import Note from '../../../../models/note';
 import Mute from '../../../../models/mute';
 import { getFriends } from '../../common/get-friends';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 import { countIf } from '../../../../prelude/array';
 
 export const meta = {
@@ -91,13 +90,10 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
-		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
+		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
 	}
 
 	const [followings, mutedUserIds] = await Promise.all([
@@ -246,13 +242,11 @@ export default async (params: any, user: ILocalUser) => {
 	}
 	//#endregion
 
-	// Issue query
 	const timeline = await Note
 		.find(query, {
 			limit: ps.limit,
 			sort: sort
 		});
 
-	// Serialize
-	return await packMany(timeline, user);
-};
+	res(await packMany(timeline, user));
+}));
diff --git a/src/server/api/endpoints/notes/local-timeline.ts b/src/server/api/endpoints/notes/local-timeline.ts
index 78ddf0062680d42456b342f12c33161e02b97cae..4446f52cdc8e59aaabe743733c510e70ec0735cd 100644
--- a/src/server/api/endpoints/notes/local-timeline.ts
+++ b/src/server/api/endpoints/notes/local-timeline.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
 import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 import { countIf } from '../../../../prelude/array';
 
 export const meta = {
@@ -66,13 +65,10 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
-		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
+		return rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
 	}
 
 	// ミュートしているユーザーを取得
@@ -150,13 +146,11 @@ export default async (params: any, user: ILocalUser) => {
 	}
 	//#endregion
 
-	// Issue query
 	const timeline = await Note
 		.find(query, {
 			limit: ps.limit,
 			sort: sort
 		});
 
-	// Serialize
-	return await packMany(timeline, user);
-};
+	res(await packMany(timeline, user));
+}));
diff --git a/src/server/api/endpoints/notes/mentions.ts b/src/server/api/endpoints/notes/mentions.ts
index 3fc397707504892a00accd94b1d13bc852c34fb6..718f5e44032c8985670157b54e01a55476e1e430 100644
--- a/src/server/api/endpoints/notes/mentions.ts
+++ b/src/server/api/endpoints/notes/mentions.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
 import { getFriendIds } from '../../common/get-friends';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 import read from '../../../../services/note/read';
 
 export const meta = {
@@ -41,10 +40,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -96,4 +92,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await packMany(mentions, user));
 
 	mentions.forEach(note => read(user._id, note._id));
-});
+}));
diff --git a/src/server/api/endpoints/notes/polls/recommendation.ts b/src/server/api/endpoints/notes/polls/recommendation.ts
index 34250a32f91328d68479e8270aa19fbe0ff44e9e..cfcba788ec0d4e33d24d6740c8b44707b7c86cce 100644
--- a/src/server/api/endpoints/notes/polls/recommendation.ts
+++ b/src/server/api/endpoints/notes/polls/recommendation.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import Vote from '../../../../../models/poll-vote';
 import Note, { pack } from '../../../../../models/note';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -25,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get votes
 	const votes = await Vote.find({
 		userId: user._id
@@ -64,4 +60,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await Promise.all(notes.map(note => pack(note, user, {
 		detail: true
 	}))));
-});
+}));
diff --git a/src/server/api/endpoints/notes/polls/vote.ts b/src/server/api/endpoints/notes/polls/vote.ts
index 32dcefec7b92c92c08e5c289dfd7672df0fd6e9b..f50e84ba1315efd0bcfd49d707e8147bde9b0a7a 100644
--- a/src/server/api/endpoints/notes/polls/vote.ts
+++ b/src/server/api/endpoints/notes/polls/vote.ts
@@ -5,8 +5,7 @@ import Watching from '../../../../../models/note-watching';
 import watch from '../../../../../services/note/watch';
 import { publishNoteStream } from '../../../../../stream';
 import notify from '../../../../../notify';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -30,10 +29,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get votee
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -114,4 +110,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	if (user.settings.autoWatch !== false) {
 		watch(user._id, note);
 	}
-});
+}));
diff --git a/src/server/api/endpoints/notes/reactions.ts b/src/server/api/endpoints/notes/reactions.ts
index 1ab5afaba1b4bcb3e48439a623bd7e28970b2c86..a1b249638f5b4afdb26c8fcca5277f0b85e876e7 100644
--- a/src/server/api/endpoints/notes/reactions.ts
+++ b/src/server/api/endpoints/notes/reactions.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
 import Reaction, { pack } from '../../../../models/note-reaction';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -44,10 +43,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -90,4 +86,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Serialize
 	res(await Promise.all(reactions.map(reaction => pack(reaction, user))));
-});
+}));
diff --git a/src/server/api/endpoints/notes/reactions/create.ts b/src/server/api/endpoints/notes/reactions/create.ts
index f2b06473a5312b3f6cf8d7832ae270b7fea25392..c9f70d96585885f0d7c11dbd8596afe2fc37f461 100644
--- a/src/server/api/endpoints/notes/reactions/create.ts
+++ b/src/server/api/endpoints/notes/reactions/create.ts
@@ -2,8 +2,7 @@ import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id
 import Note from '../../../../../models/note';
 import create from '../../../../../services/note/reaction/create';
 import { validateReaction } from '../../../../../models/note-reaction';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -35,10 +34,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch reactee
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -59,4 +55,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	}
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/notes/reactions/delete.ts b/src/server/api/endpoints/notes/reactions/delete.ts
index 2a2577dfe6434ccd8dc2946eaebaa7dd63ee5aa2..60f49fb2752ae51eb08515ebab892a00417df4bc 100644
--- a/src/server/api/endpoints/notes/reactions/delete.ts
+++ b/src/server/api/endpoints/notes/reactions/delete.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import Reaction from '../../../../../models/note-reaction';
 import Note from '../../../../../models/note';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -22,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch unreactee
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -64,4 +60,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	Note.update({ _id: note._id }, {
 		$inc: dec
 	});
-});
+}));
diff --git a/src/server/api/endpoints/notes/renotes.ts b/src/server/api/endpoints/notes/renotes.ts
index ff926806ebba748e5224a2172843a0245cbcc05d..85d5820e581676750bd9db044702c3a03a593448 100644
--- a/src/server/api/endpoints/notes/renotes.ts
+++ b/src/server/api/endpoints/notes/renotes.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note, { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -34,10 +33,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if both of sinceId and untilId is specified
 	if (ps.sinceId && ps.untilId) {
 		return rej('cannot set sinceId and untilId');
@@ -78,4 +74,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 		});
 
 	res(await packMany(renotes, user));
-});
+}));
diff --git a/src/server/api/endpoints/notes/replies.ts b/src/server/api/endpoints/notes/replies.ts
index 86a75c1cab2f410405bb86e7153ad2964051a0f1..8b5a3593d1303c67e46900db26a9479b7e7c0af6 100644
--- a/src/server/api/endpoints/notes/replies.ts
+++ b/src/server/api/endpoints/notes/replies.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note, { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -29,10 +28,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Lookup note
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -45,4 +41,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	const ids = (note._replyIds || []).slice(ps.offset, ps.offset + ps.limit);
 
 	res(await packMany(ids, user));
-});
+}));
diff --git a/src/server/api/endpoints/notes/search.ts b/src/server/api/endpoints/notes/search.ts
index 63a87c0f5686fc4f13a6c488586a871a0b6a9b31..e107ca4e15d0541bad2229f78be8d109323e6cf3 100644
--- a/src/server/api/endpoints/notes/search.ts
+++ b/src/server/api/endpoints/notes/search.ts
@@ -1,10 +1,9 @@
 import $ from 'cafy';
 import * as mongo from 'mongodb';
 import Note from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
 import { packMany } from '../../../../models/note';
 import es from '../../../../db/elasticsearch';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -31,10 +30,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	if (es == null) return rej('searching not available');
 
 	es.search({
@@ -79,4 +75,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 
 		res(await packMany(notes, me));
 	});
-});
+}));
diff --git a/src/server/api/endpoints/notes/search_by_tag.ts b/src/server/api/endpoints/notes/search_by_tag.ts
index 99a6dce8344224b0b41b890365df67f4c232ddc3..fcc33d14f3b7825bd8b7ff83ea5474e703ced6aa 100644
--- a/src/server/api/endpoints/notes/search_by_tag.ts
+++ b/src/server/api/endpoints/notes/search_by_tag.ts
@@ -1,10 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
 import Mute from '../../../../models/mute';
 import { getFriendIds } from '../../common/get-friends';
 import { packMany } from '../../../../models/note';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -103,10 +102,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	const q: any = {
 		$and: [ps.tag ? {
 			tagsLower: ps.tag.toLowerCase()
@@ -322,4 +318,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 
 	// Serialize
 	res(await packMany(notes, me));
-});
+}));
diff --git a/src/server/api/endpoints/notes/show.ts b/src/server/api/endpoints/notes/show.ts
index 8b426c0053ec976d63f1144d24150cdba368f445..53246102d0ce197e0250756ca8dbf50a5d66169b 100644
--- a/src/server/api/endpoints/notes/show.ts
+++ b/src/server/api/endpoints/notes/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note, { pack } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	stability: 'stable',
@@ -25,10 +24,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Get note
 	const note = await Note.findOne({
 		_id: ps.noteId
@@ -42,4 +38,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	res(await pack(note, user, {
 		detail: true
 	}));
-});
+}));
diff --git a/src/server/api/endpoints/notes/timeline.ts b/src/server/api/endpoints/notes/timeline.ts
index 8834645fc87e1aea3dc54cc03cc4b45c30a0dafe..3c970c03a1818ddf3bb444989feed9a6803e6276 100644
--- a/src/server/api/endpoints/notes/timeline.ts
+++ b/src/server/api/endpoints/notes/timeline.ts
@@ -3,8 +3,7 @@ import Note from '../../../../models/note';
 import Mute from '../../../../models/mute';
 import { getFriends } from '../../common/get-friends';
 import { packMany } from '../../../../models/note';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 import { countIf } from '../../../../prelude/array';
 
 export const meta = {
@@ -94,13 +93,11 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Check if only one of sinceId, untilId, sinceDate, untilDate specified
 	if (countIf(x => x != null, [ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate]) > 1) {
-		throw 'only one of sinceId, untilId, sinceDate, untilDate can be specified';
+		rej('only one of sinceId, untilId, sinceDate, untilDate can be specified');
+		return;
 	}
 
 	const [followings, mutedUserIds] = await Promise.all([
@@ -251,5 +248,5 @@ export default async (params: any, user: ILocalUser) => {
 		});
 
 	// Serialize
-	return await packMany(timeline, user);
-};
+	res(await packMany(timeline, user));
+}));
diff --git a/src/server/api/endpoints/notes/user-list-timeline.ts b/src/server/api/endpoints/notes/user-list-timeline.ts
index 3bdcc6c1215f8dcf195624d985b9bb3eb78eac9c..156ffbbc329d23b525e9c11b34f8d6e335091c10 100644
--- a/src/server/api/endpoints/notes/user-list-timeline.ts
+++ b/src/server/api/endpoints/notes/user-list-timeline.ts
@@ -3,8 +3,7 @@ import Note from '../../../../models/note';
 import Mute from '../../../../models/mute';
 import { packMany } from '../../../../models/note';
 import UserList from '../../../../models/user-list';
-import { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -101,10 +100,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) throw psErr;
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const [list, mutedUserIds] = await Promise.all([
 		// リストを取得
 		// Fetch the list
@@ -120,7 +116,8 @@ export default async (params: any, user: ILocalUser) => {
 	]);
 
 	if (list.userIds.length == 0) {
-		return [];
+		res([]);
+		return;
 	}
 
 	//#region Construct query
@@ -258,5 +255,5 @@ export default async (params: any, user: ILocalUser) => {
 		});
 
 	// Serialize
-	return await packMany(timeline, user);
-};
+	res(await packMany(timeline, user));
+}));
diff --git a/src/server/api/endpoints/notifications/mark_all_as_read.ts b/src/server/api/endpoints/notifications/mark_all_as_read.ts
index 6487cd8b485f7a846c74af1b615e3e9093876946..1b5208d447718c080c461e346c99a8c46aba0c57 100644
--- a/src/server/api/endpoints/notifications/mark_all_as_read.ts
+++ b/src/server/api/endpoints/notifications/mark_all_as_read.ts
@@ -1,6 +1,7 @@
 import Notification from '../../../../models/notification';
 import { publishMainStream } from '../../../../stream';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -13,10 +14,7 @@ export const meta = {
 	kind: 'notification-write'
 };
 
-/**
- * Mark all notifications as read
- */
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Update documents
 	await Notification.update({
 		notifieeId: user._id,
@@ -41,4 +39,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// 全ての通知を読みましたよというイベントを発行
 	publishMainStream(user._id, 'readAllNotifications');
-});
+}));
diff --git a/src/server/api/endpoints/stats.ts b/src/server/api/endpoints/stats.ts
index fc195da22d35fa77f3386b6d89d66c195113efa4..56549848dcd861ea71acc57e7a4493db200ee095 100644
--- a/src/server/api/endpoints/stats.ts
+++ b/src/server/api/endpoints/stats.ts
@@ -1,10 +1,19 @@
 import Meta from '../../../models/meta';
+import define from '../define';
 
-/**
- * Get the misskey's statistics
- */
-export default () => new Promise(async (res, rej) => {
+export const meta = {
+	requireCredential: false,
+
+	desc: {
+		'en-US': 'Get the instance\'s statistics'
+	},
+
+	params: {
+	}
+};
+
+export default define(meta, () => new Promise(async (res, rej) => {
 	const meta = await Meta.findOne();
 
 	res(meta ? meta.stats : {});
-});
+}));
diff --git a/src/server/api/endpoints/sw/register.ts b/src/server/api/endpoints/sw/register.ts
index 69337bd8c0018bb4cfde158a5ec5dd2a89d8f1fe..26427452fd45bfa034766c60e120d7950f5f13d3 100644
--- a/src/server/api/endpoints/sw/register.ts
+++ b/src/server/api/endpoints/sw/register.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import Subscription from '../../../../models/sw-subscription';
-import { ILocalUser } from '../../../../models/user';
 import config from '../../../../config';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: true,
@@ -22,10 +21,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// if already subscribed
 	const exist = await Subscription.findOne({
 		userId: user._id,
@@ -53,4 +49,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 		state: 'subscribed',
 		key: config.sw.public_key
 	});
-});
+}));
diff --git a/src/server/api/endpoints/username/available.ts b/src/server/api/endpoints/username/available.ts
index b61be84c3b29f68ca1750dd7671ffd7d18a67e61..a5f0b5943fea87fc3b08e24c7defb4d3ac6f587b 100644
--- a/src/server/api/endpoints/username/available.ts
+++ b/src/server/api/endpoints/username/available.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 import User from '../../../../models/user';
 import { validateUsername } from '../../../../models/user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -13,10 +13,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps) => new Promise(async (res, rej) => {
 	// Get exist
 	const exist = await User
 		.count({
@@ -30,4 +27,4 @@ export default async (params: any) => new Promise(async (res, rej) => {
 	res({
 		available: exist === 0
 	});
-});
+}));
diff --git a/src/server/api/endpoints/users.ts b/src/server/api/endpoints/users.ts
index 81751504e7b19347e685909d5611cfb3dd08a1a0..6fb50e6712adb91ffc7713c6dd05a9a7689a5daa 100644
--- a/src/server/api/endpoints/users.ts
+++ b/src/server/api/endpoints/users.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy';
 import User, { pack, ILocalUser } from '../../../models/user';
-import getParams from '../get-params';
+import define from '../define';
 
 export const meta = {
 	requireCredential: false,
@@ -22,10 +22,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	let _sort;
 	if (ps.sort) {
 		if (ps.sort == '+follower') {
@@ -53,4 +50,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		});
 
 	res(await Promise.all(users.map(user => pack(user, me))));
-});
+}));
diff --git a/src/server/api/endpoints/users/followers.ts b/src/server/api/endpoints/users/followers.ts
index 71081835c78187e0b3a8239c62ae2e29544853da..9e3a30f6f12f4d9162514408abfdf98c2bce095d 100644
--- a/src/server/api/endpoints/users/followers.ts
+++ b/src/server/api/endpoints/users/followers.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import Following from '../../../../models/following';
 import { pack } from '../../../../models/user';
 import { getFriendIds } from '../../common/get-friends';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -37,10 +37,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Lookup user
 	const user = await User.findOne({
 		_id: ps.userId
@@ -95,4 +92,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		users: users,
 		next: inStock ? following[following.length - 1]._id : null,
 	});
-});
+}));
diff --git a/src/server/api/endpoints/users/following.ts b/src/server/api/endpoints/users/following.ts
index 778ef54a2747400bcea9c436aa076778fa8d5e02..57bf1e1e8b29e97747fed4c9311e32ec61137b02 100644
--- a/src/server/api/endpoints/users/following.ts
+++ b/src/server/api/endpoints/users/following.ts
@@ -1,9 +1,9 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
-import User, { ILocalUser } from '../../../../models/user';
+import User from '../../../../models/user';
 import Following from '../../../../models/following';
 import { pack } from '../../../../models/user';
 import { getFriendIds } from '../../common/get-friends';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -37,10 +37,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Lookup user
 	const user = await User.findOne({
 		_id: ps.userId
@@ -95,4 +92,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 		users: users,
 		next: inStock ? following[following.length - 1]._id : null,
 	});
-});
+}));
diff --git a/src/server/api/endpoints/users/get_frequently_replied_users.ts b/src/server/api/endpoints/users/get_frequently_replied_users.ts
index b0fd259588c7f0456f2eaac93c23bb53b140fd17..6b8b985eea455b011beb8b2ff5e2e29dfd8e8a85 100644
--- a/src/server/api/endpoints/users/get_frequently_replied_users.ts
+++ b/src/server/api/endpoints/users/get_frequently_replied_users.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import Note from '../../../../models/note';
-import User, { pack, ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import User, { pack } from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	requireCredential: false,
@@ -19,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Lookup user
 	const user = await User.findOne({
 		_id: ps.userId
@@ -104,4 +101,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 	})));
 
 	res(repliesObj);
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/create.ts b/src/server/api/endpoints/users/lists/create.ts
index c14bb64daaa57d022bdb240ae7681069dd6af02a..d93cf13d942064a977f2174ea1c203ac9e1f8524 100644
--- a/src/server/api/endpoints/users/lists/create.ts
+++ b/src/server/api/endpoints/users/lists/create.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy';
 import UserList, { pack } from '../../../../../models/user-list';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -20,10 +19,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// insert
 	const userList = await UserList.insert({
 		createdAt: new Date(),
@@ -34,4 +30,4 @@ export default async (params: any, user: ILocalUser) => new Promise(async (res,
 
 	// Response
 	res(await pack(userList));
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/delete.ts b/src/server/api/endpoints/users/lists/delete.ts
index 1d4513a8227270f770901b0cc31842e417fac587..8d297198c92841062984280e7c0358d9db4aee9a 100644
--- a/src/server/api/endpoints/users/lists/delete.ts
+++ b/src/server/api/endpoints/users/lists/delete.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../../misc/cafy-id';
 import UserList from '../../../../../models/user-list';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -26,10 +25,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	const userList = await UserList.findOne({
 		_id: ps.listId,
 		userId: user._id
@@ -44,4 +40,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 	});
 
 	res();
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/list.ts b/src/server/api/endpoints/users/lists/list.ts
index 966e1d3ad99afe34f3cf7252ca3f241b44337cdf..8f9775e19bb9a8a5164c6c2a74f523eb0603b545 100644
--- a/src/server/api/endpoints/users/lists/list.ts
+++ b/src/server/api/endpoints/users/lists/list.ts
@@ -1,5 +1,5 @@
 import UserList, { pack } from '../../../../../models/user-list';
-import { ILocalUser } from '../../../../../models/user';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -11,11 +11,11 @@ export const meta = {
 	kind: 'account-read'
 };
 
-export default async (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Fetch lists
 	const userLists = await UserList.find({
 		userId: me._id,
 	});
 
 	res(await Promise.all(userLists.map(x => pack(x))));
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/push.ts b/src/server/api/endpoints/users/lists/push.ts
index 8208e627ed3b866e63a856a3a09f0b680938449b..5c11f25dc49117d0356f380f090804d06b386cbf 100644
--- a/src/server/api/endpoints/users/lists/push.ts
+++ b/src/server/api/endpoints/users/lists/push.ts
@@ -1,11 +1,11 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import UserList from '../../../../../models/user-list';
-import User, { pack as packUser, isRemoteUser, getGhost, ILocalUser } from '../../../../../models/user';
+import User, { pack as packUser, isRemoteUser, getGhost } from '../../../../../models/user';
 import { publishUserListStream } from '../../../../../stream';
 import ap from '../../../../../remote/activitypub/renderer';
 import renderFollow from '../../../../../remote/activitypub/renderer/follow';
 import { deliver } from '../../../../../queue';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -30,10 +30,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Fetch the list
 	const userList = await UserList.findOne({
 		_id: ps.listId,
@@ -74,4 +71,4 @@ export default async (params: any, me: ILocalUser) => new Promise(async (res, re
 		const content = ap(renderFollow(ghost, user));
 		deliver(ghost, content, user.inbox);
 	}
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/show.ts b/src/server/api/endpoints/users/lists/show.ts
index 585833a2feb6788043f23675b0c93302022a2e0a..2662ab27696e0bfcc83e95f656eac9754e58a791 100644
--- a/src/server/api/endpoints/users/lists/show.ts
+++ b/src/server/api/endpoints/users/lists/show.ts
@@ -1,7 +1,6 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../../misc/cafy-id';
 import UserList, { pack } from '../../../../../models/user-list';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -21,10 +20,7 @@ export const meta = {
 	}
 };
 
-export default async (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	// Fetch the list
 	const userList = await UserList.findOne({
 		_id: ps.listId,
@@ -36,4 +32,4 @@ export default async (params: any, me: ILocalUser) => new Promise(async (res, re
 	}
 
 	res(await pack(userList));
-});
+}));
diff --git a/src/server/api/endpoints/users/lists/update.ts b/src/server/api/endpoints/users/lists/update.ts
index fb1a37b2f1d91906d6da30f3ba2b1d3fa242d618..79a7da5658377eb961588deb11f04696cf1698b2 100644
--- a/src/server/api/endpoints/users/lists/update.ts
+++ b/src/server/api/endpoints/users/lists/update.ts
@@ -1,8 +1,7 @@
 import $ from 'cafy';
 import ID, { transform } from '../../../../../misc/cafy-id';
 import UserList, { pack } from '../../../../../models/user-list';
-import { ILocalUser } from '../../../../../models/user';
-import getParams from '../../../get-params';
+import define from '../../../define';
 
 export const meta = {
 	desc: {
@@ -34,10 +33,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, user: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, user) => new Promise(async (res, rej) => {
 	// Fetch the list
 	const userList = await UserList.findOne({
 		_id: ps.listId,
@@ -57,4 +53,4 @@ export default (params: any, user: ILocalUser) => new Promise(async (res, rej) =
 
 	// Response
 	res(await pack(userList._id));
-});
+}));
diff --git a/src/server/api/endpoints/users/notes.ts b/src/server/api/endpoints/users/notes.ts
index ac6601f64fecb85cd672ccd488fab4632f321874..4bbacab2bf3b01a4ff0c5130791ecdc372525af9 100644
--- a/src/server/api/endpoints/users/notes.ts
+++ b/src/server/api/endpoints/users/notes.ts
@@ -1,8 +1,8 @@
 import $ from 'cafy'; import ID, { transform } from '../../../../misc/cafy-id';
 import getHostLower from '../../common/get-host-lower';
 import Note, { packMany } from '../../../../models/note';
-import User, { ILocalUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import User from '../../../../models/user';
+import define from '../../define';
 import { countIf } from '../../../../prelude/array';
 
 export const meta = {
@@ -126,10 +126,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	if (ps.userId === undefined && ps.username === undefined) {
 		return rej('userId or username is required');
 	}
@@ -215,4 +212,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 
 	// Serialize
 	res(await packMany(notes, me));
-});
+}));
diff --git a/src/server/api/endpoints/users/recommendation.ts b/src/server/api/endpoints/users/recommendation.ts
index 47c809ee4cad194c699b34f11d1349ec01671855..127029f83c4b84241ae0c2758f72ae240976c496 100644
--- a/src/server/api/endpoints/users/recommendation.ts
+++ b/src/server/api/endpoints/users/recommendation.ts
@@ -1,11 +1,11 @@
 const ms = require('ms');
 import $ from 'cafy';
-import User, { pack, ILocalUser } from '../../../../models/user';
+import User, { pack } from '../../../../models/user';
 import { getFriendIds } from '../../common/get-friends';
 import Mute from '../../../../models/mute';
 import * as request from 'request';
 import config from '../../../../config';
-import getParams from '../../get-params';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -29,22 +29,19 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	if (config.user_recommendation && config.user_recommendation.external) {
 		const userName = me.username;
 		const hostName = config.hostname;
-		const limit = params.limit;
-		const offset = params.offset;
+		const limit = ps.limit;
+		const offset = ps.offset;
 		const timeout = config.user_recommendation.timeout;
 		const engine = config.user_recommendation.engine;
 		const url = engine
 			.replace('{{host}}', hostName)
 			.replace('{{user}}', userName)
-			.replace('{{limit}}', limit)
-			.replace('{{offset}}', offset);
+			.replace('{{limit}}', limit.toString())
+			.replace('{{offset}}', offset.toString());
 
 		request({
 			url: url,
@@ -89,4 +86,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 
 		res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
 	}
-});
+}));
diff --git a/src/server/api/endpoints/users/relation.ts b/src/server/api/endpoints/users/relation.ts
index 19643ceed0c50ce9f50da069dac31dd92452aa49..c63ec337bf4b71d64d1a76ed77754073e6c81836 100644
--- a/src/server/api/endpoints/users/relation.ts
+++ b/src/server/api/endpoints/users/relation.ts
@@ -1,6 +1,6 @@
 import $ from 'cafy'; import ID, { transform, ObjectId } from '../../../../misc/cafy-id';
-import { ILocalUser, getRelation } from '../../../../models/user';
-import getParams from '../../get-params';
+import { getRelation } from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -20,13 +20,10 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	const ids = Array.isArray(ps.userId) ? ps.userId : [ps.userId];
 
 	const relations = await Promise.all(ids.map(id => getRelation(me._id, id)));
 
 	res(Array.isArray(ps.userId) ? relations : relations[0]);
-});
+}));
diff --git a/src/server/api/endpoints/users/search.ts b/src/server/api/endpoints/users/search.ts
index a2077b589d0482e300fec1ad9ab89bf0db602b8e..edc4d603ca37059dcc90dfc9823a7d5df5faf127 100644
--- a/src/server/api/endpoints/users/search.ts
+++ b/src/server/api/endpoints/users/search.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy';
 const escapeRegexp = require('escape-regexp');
-import User, { pack, ILocalUser, validateUsername, IUser } from '../../../../models/user';
-import getParams from '../../get-params';
+import User, { pack, validateUsername, IUser } from '../../../../models/user';
+import define from '../../define';
 
 export const meta = {
 	desc: {
@@ -44,13 +44,7 @@ export const meta = {
 	},
 };
 
-/**
- * Search a user
- */
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	const isUsername = validateUsername(ps.query.replace('@', ''));
 
 	let users: IUser[] = [];
@@ -158,4 +152,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 
 	// Serialize
 	res(await Promise.all(users.map(user => pack(user, me, { detail: true }))));
-});
+}));
diff --git a/src/server/api/endpoints/users/show.ts b/src/server/api/endpoints/users/show.ts
index c6f01593d4d681e95f57b241bad8b38c04f7166e..93223b3f9ff4e3f1e6a27cf25d6f28f1095603a0 100644
--- a/src/server/api/endpoints/users/show.ts
+++ b/src/server/api/endpoints/users/show.ts
@@ -1,7 +1,7 @@
 import $ from 'cafy'; import ID, { transform, transformMany } from '../../../../misc/cafy-id';
-import User, { pack, ILocalUser, isRemoteUser } from '../../../../models/user';
+import User, { pack, isRemoteUser } from '../../../../models/user';
 import resolveRemoteUser from '../../../../remote/resolve-user';
-import getParams from '../../get-params';
+import define from '../../define';
 
 const cursorOption = { fields: { data: false } };
 
@@ -39,10 +39,7 @@ export const meta = {
 	}
 };
 
-export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
-	const [ps, psErr] = getParams(meta, params);
-	if (psErr) return rej(psErr);
-
+export default define(meta, (ps, me) => new Promise(async (res, rej) => {
 	let user;
 
 	if (ps.userIds) {
@@ -87,4 +84,4 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
 			}
 		}
 	}
-});
+}));
diff --git a/src/server/api/get-params.ts b/src/server/api/get-params.ts
deleted file mode 100644
index 60d038990e6910de37e002e08995e4846c099a60..0000000000000000000000000000000000000000
--- a/src/server/api/get-params.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { IEndpointMeta } from './endpoints';
-
-export default function <T extends IEndpointMeta>(defs: T, params: any): [{
-	[P in keyof T['params']]: T['params'][P]['transform'] extends Function
-		? ReturnType<T['params'][P]['transform']>
-		: ReturnType<T['params'][P]['validator']['get']>[0];
-}, Error] {
-	const x: any = {};
-	let err: Error = null;
-	Object.entries(defs.params).some(([k, def]) => {
-		const [v, e] = def.validator.get(params[k]);
-		if (e) {
-			err = new Error(e.message);
-			err.name = 'INVALID_PARAM';
-			(err as any).param = k;
-			return true;
-		} else {
-			if (v === undefined && def.default) {
-				x[k] = def.default;
-			} else {
-				x[k] = v;
-			}
-			if (def.transform) x[k] = def.transform(x[k]);
-			return false;
-		}
-	});
-	return [x, err];
-}