diff --git a/package.json b/package.json
index 6f1c8f1e31..60e5098033 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
     "@types/websocket": "0.0.33",
     "autwh": "0.0.1",
     "bcryptjs": "2.4.3",
-    "cafy": "1.2.0",
+    "cafy": "2.3.0",
     "body-parser": "1.17.1",
     "chai": "3.5.0",
     "chai-http": "3.0.0",
diff --git a/src/api/endpoints/aggregation/posts/like.ts b/src/api/endpoints/aggregation/posts/like.ts
index 38f79a1202..3f44413fe8 100644
--- a/src/api/endpoints/aggregation/posts/like.ts
+++ b/src/api/endpoints/aggregation/posts/like.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../../models/post';
 import Like from '../../../models/like';
 
@@ -13,7 +13,7 @@ import Like from '../../../models/like';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id).expect.id().required().get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Lookup post
diff --git a/src/api/endpoints/aggregation/posts/likes.ts b/src/api/endpoints/aggregation/posts/likes.ts
index 773f78b6f3..454368eded 100644
--- a/src/api/endpoints/aggregation/posts/likes.ts
+++ b/src/api/endpoints/aggregation/posts/likes.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../../models/post';
 import Like from '../../../models/like';
 
@@ -13,7 +13,7 @@ import Like from '../../../models/like';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id).expect.id().required().get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Lookup post
diff --git a/src/api/endpoints/aggregation/posts/reply.ts b/src/api/endpoints/aggregation/posts/reply.ts
index 06f94f668e..c7ba413311 100644
--- a/src/api/endpoints/aggregation/posts/reply.ts
+++ b/src/api/endpoints/aggregation/posts/reply.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../../models/post';
 
 /**
@@ -12,7 +12,7 @@ import Post from '../../../models/post';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id).expect.id().required().get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Lookup post
diff --git a/src/api/endpoints/aggregation/posts/repost.ts b/src/api/endpoints/aggregation/posts/repost.ts
index 939f027d56..88d21243f8 100644
--- a/src/api/endpoints/aggregation/posts/repost.ts
+++ b/src/api/endpoints/aggregation/posts/repost.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../../models/post';
 
 /**
@@ -12,7 +12,7 @@ import Post from '../../../models/post';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id).expect.id().required().get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Lookup post
diff --git a/src/api/endpoints/aggregation/users/followers.ts b/src/api/endpoints/aggregation/users/followers.ts
index a5438502aa..3022b2b002 100644
--- a/src/api/endpoints/aggregation/users/followers.ts
+++ b/src/api/endpoints/aggregation/users/followers.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../../models/user';
 import Following from '../../../models/following';
 
@@ -13,7 +13,7 @@ import Following from '../../../models/following';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id).expect.id().required().get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Lookup user
diff --git a/src/api/endpoints/aggregation/users/following.ts b/src/api/endpoints/aggregation/users/following.ts
index 1b88cd2349..92da7e6921 100644
--- a/src/api/endpoints/aggregation/users/following.ts
+++ b/src/api/endpoints/aggregation/users/following.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../../models/user';
 import Following from '../../../models/following';
 
@@ -13,7 +13,7 @@ import Following from '../../../models/following';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id).expect.id().required().get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Lookup user
diff --git a/src/api/endpoints/aggregation/users/like.ts b/src/api/endpoints/aggregation/users/like.ts
index 0fce7466f8..239acd2931 100644
--- a/src/api/endpoints/aggregation/users/like.ts
+++ b/src/api/endpoints/aggregation/users/like.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../../models/user';
 import Like from '../../../models/like';
 
@@ -13,7 +13,7 @@ import Like from '../../../models/like';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id).expect.id().required().get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Lookup user
diff --git a/src/api/endpoints/aggregation/users/post.ts b/src/api/endpoints/aggregation/users/post.ts
index 85a702045a..cb6bae4970 100644
--- a/src/api/endpoints/aggregation/users/post.ts
+++ b/src/api/endpoints/aggregation/users/post.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../../models/user';
 import Post from '../../../models/post';
 
@@ -13,7 +13,7 @@ import Post from '../../../models/post';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id).expect.id().required().get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Lookup user
diff --git a/src/api/endpoints/app/create.ts b/src/api/endpoints/app/create.ts
index 43f533d216..498c4f144e 100644
--- a/src/api/endpoints/app/create.ts
+++ b/src/api/endpoints/app/create.ts
@@ -2,7 +2,7 @@
  * Module dependencies
  */
 import rndstr from 'rndstr';
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../models/app';
 import { isValidNameId } from '../../models/app';
 import serialize from '../../serializers/app';
@@ -69,24 +69,24 @@ import serialize from '../../serializers/app';
  */
 module.exports = async (params, user) => new Promise(async (res, rej) => {
 	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = it(params.name_id).expect.string().required().validate(isValidNameId).get();
+	const [nameId, nameIdErr] = $(params.name_id).string().pipe(isValidNameId).$;
 	if (nameIdErr) return rej('invalid name_id param');
 
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().required().get();
+	const [name, nameErr] = $(params.name).string().$;
 	if (nameErr) return rej('invalid name param');
 
 	// Get 'description' parameter
-	const [description, descriptionErr] = it(params.description).expect.string().required().get();
+	const [description, descriptionErr] = $(params.description).string().$;
 	if (descriptionErr) return rej('invalid description param');
 
 	// Get 'permission' parameter
-	const [permission, permissionErr] = it(params.permission).expect.array().unique().allString().required().get();
+	const [permission, permissionErr] = $(params.permission).array('string').unique().$;
 	if (permissionErr) return rej('invalid permission param');
 
 	// Get 'callback_url' parameter
-	// TODO: Check it is valid url
-	const [callbackUrl = null, callbackUrlErr] = it(params.callback_url).expect.nullable.string().get();
+	// TODO: Check $ is valid url
+	const [callbackUrl = null, callbackUrlErr] = $(params.callback_url).optional.nullable.string().$;
 	if (callbackUrlErr) return rej('invalid callback_url param');
 
 	// Generate secret
diff --git a/src/api/endpoints/app/name_id/available.ts b/src/api/endpoints/app/name_id/available.ts
index ac38c89847..3d2c710322 100644
--- a/src/api/endpoints/app/name_id/available.ts
+++ b/src/api/endpoints/app/name_id/available.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../../models/app';
 import { isValidNameId } from '../../../models/app';
 
@@ -42,7 +42,7 @@ import { isValidNameId } from '../../../models/app';
  */
 module.exports = async (params) => new Promise(async (res, rej) => {
 	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = it(params.name_id).expect.string().required().validate(isValidNameId).get();
+	const [nameId, nameIdErr] = $(params.name_id).string().pipe(isValidNameId).$;
 	if (nameIdErr) return rej('invalid name_id param');
 
 	// Get exist
diff --git a/src/api/endpoints/app/show.ts b/src/api/endpoints/app/show.ts
index 88698d5cd8..054aab8596 100644
--- a/src/api/endpoints/app/show.ts
+++ b/src/api/endpoints/app/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../models/app';
 import serialize from '../../serializers/app';
 
@@ -46,11 +46,11 @@ import serialize from '../../serializers/app';
  */
 module.exports = (params, user, _, isSecure) => new Promise(async (res, rej) => {
 	// Get 'app_id' parameter
-	const [appId, appIdErr] = it(params.app_id, 'id').get();
+	const [appId, appIdErr] = $(params.app_id).optional.id().$;
 	if (appIdErr) return rej('invalid app_id param');
 
 	// Get 'name_id' parameter
-	const [nameId, nameIdErr] = it(params.name_id, 'string').get();
+	const [nameId, nameIdErr] = $(params.name_id).optional.string().$;
 	if (nameIdErr) return rej('invalid name_id param');
 
 	if (appId === undefined && nameId === undefined) {
diff --git a/src/api/endpoints/auth/accept.ts b/src/api/endpoints/auth/accept.ts
index fc74979bb3..4ee20a6d25 100644
--- a/src/api/endpoints/auth/accept.ts
+++ b/src/api/endpoints/auth/accept.ts
@@ -3,7 +3,7 @@
  */
 import rndstr from 'rndstr';
 const crypto = require('crypto');
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../models/app';
 import AuthSess from '../../models/auth-session';
 import AccessToken from '../../models/access-token';
@@ -40,7 +40,7 @@ import AccessToken from '../../models/access-token';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'token' parameter
-	const [token, tokenErr] = it(params.token).expect.string().required().get();
+	const [token, tokenErr] = $(params.token).string().$;
 	if (tokenErr) return rej('invalid token param');
 
 	// Fetch token
diff --git a/src/api/endpoints/auth/session/generate.ts b/src/api/endpoints/auth/session/generate.ts
index 2378d123f3..510382247e 100644
--- a/src/api/endpoints/auth/session/generate.ts
+++ b/src/api/endpoints/auth/session/generate.ts
@@ -2,7 +2,7 @@
  * Module dependencies
  */
 import * as uuid from 'uuid';
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../../models/app';
 import AuthSess from '../../../models/auth-session';
 import config from '../../../../conf';
@@ -46,7 +46,7 @@ import config from '../../../../conf';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'app_secret' parameter
-	const [appSecret, appSecretErr] = it(params.app_secret).expect.string().required().get();
+	const [appSecret, appSecretErr] = $(params.app_secret).string().$;
 	if (appSecretErr) return rej('invalid app_secret param');
 
 	// Lookup app
diff --git a/src/api/endpoints/auth/session/show.ts b/src/api/endpoints/auth/session/show.ts
index e16943683f..ede8a67634 100644
--- a/src/api/endpoints/auth/session/show.ts
+++ b/src/api/endpoints/auth/session/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import AuthSess from '../../../models/auth-session';
 import serialize from '../../../serializers/auth-session';
 
@@ -54,7 +54,7 @@ import serialize from '../../../serializers/auth-session';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'token' parameter
-	const [token, tokenErr] = it(params.token).expect.string().required().get();
+	const [token, tokenErr] = $(params.token).string().$;
 	if (tokenErr) return rej('invalid token param');
 
 	// Lookup session
diff --git a/src/api/endpoints/auth/session/userkey.ts b/src/api/endpoints/auth/session/userkey.ts
index 9816ea2051..afd3250b04 100644
--- a/src/api/endpoints/auth/session/userkey.ts
+++ b/src/api/endpoints/auth/session/userkey.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../../models/app';
 import AuthSess from '../../../models/auth-session';
 import AccessToken from '../../../models/access-token';
@@ -51,7 +51,7 @@ import serialize from '../../../serializers/user';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'app_secret' parameter
-	const [appSecret, appSecretErr] = it(params.app_secret).expect.string().required().get();
+	const [appSecret, appSecretErr] = $(params.app_secret).string().$;
 	if (appSecretErr) return rej('invalid app_secret param');
 
 	// Lookup app
@@ -64,7 +64,7 @@ module.exports = (params) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'token' parameter
-	const [token, tokenErr] = it(params.token).expect.string().required().get();
+	const [token, tokenErr] = $(params.token).string().$;
 	if (tokenErr) return rej('invalid token param');
 
 	// Fetch token
diff --git a/src/api/endpoints/drive/files.ts b/src/api/endpoints/drive/files.ts
index f9c5f49d2a..a68ae34817 100644
--- a/src/api/endpoints/drive/files.ts
+++ b/src/api/endpoints/drive/files.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFile from '../../models/drive-file';
 import serialize from '../../serializers/drive-file';
 
@@ -15,15 +15,15 @@ import serialize from '../../serializers/drive-file';
  */
 module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
@@ -32,7 +32,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Construct query
diff --git a/src/api/endpoints/drive/files/create.ts b/src/api/endpoints/drive/files/create.ts
index e75db60010..43dca7762a 100644
--- a/src/api/endpoints/drive/files/create.ts
+++ b/src/api/endpoints/drive/files/create.ts
@@ -2,7 +2,7 @@
  * Module dependencies
  */
 import * as fs from 'fs';
-import it from 'cafy';
+import $ from 'cafy';
 import { validateFileName } from '../../../models/drive-file';
 import serialize from '../../../serializers/drive-file';
 import create from '../../../common/add-file-to-drive';
@@ -39,7 +39,7 @@ module.exports = (file, params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Create file
diff --git a/src/api/endpoints/drive/files/find.ts b/src/api/endpoints/drive/files/find.ts
index 66a4f70e3f..cd0b33f2ca 100644
--- a/src/api/endpoints/drive/files/find.ts
+++ b/src/api/endpoints/drive/files/find.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFile from '../../../models/drive-file';
 import serialize from '../../../serializers/drive-file';
 
@@ -14,11 +14,11 @@ import serialize from '../../../serializers/drive-file';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().required().get();
+	const [name, nameErr] = $(params.name).string().$;
 	if (nameErr) return rej('invalid name param');
 
 	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Issue query
diff --git a/src/api/endpoints/drive/files/show.ts b/src/api/endpoints/drive/files/show.ts
index 0f22d54a4d..8dbc297e4f 100644
--- a/src/api/endpoints/drive/files/show.ts
+++ b/src/api/endpoints/drive/files/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFile from '../../../models/drive-file';
 import serialize from '../../../serializers/drive-file';
 
@@ -14,7 +14,7 @@ import serialize from '../../../serializers/drive-file';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = it(params.file_id).expect.id().required().get();
+	const [fileId, fileIdErr] = $(params.file_id).id().$;
 	if (fileIdErr) return rej('invalid file_id param');
 
 	// Fetch file
diff --git a/src/api/endpoints/drive/files/update.ts b/src/api/endpoints/drive/files/update.ts
index b5309506f2..1cfbdd8f0b 100644
--- a/src/api/endpoints/drive/files/update.ts
+++ b/src/api/endpoints/drive/files/update.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../../models/drive-folder';
 import DriveFile from '../../../models/drive-file';
 import { validateFileName } from '../../../models/drive-file';
@@ -17,7 +17,7 @@ import event from '../../../event';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = it(params.file_id).expect.id().required().get();
+	const [fileId, fileIdErr] = $(params.file_id).id().$;
 	if (fileIdErr) return rej('invalid file_id param');
 
 	// Fetch file
@@ -36,12 +36,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().validate(validateFileName).get();
+	const [name, nameErr] = $(params.name).optional.string().pipe(validateFileName).$;
 	if (nameErr) return rej('invalid name param');
 	if (name) file.name = name;
 
 	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	if (folderId !== undefined) {
diff --git a/src/api/endpoints/drive/files/upload_from_url.ts b/src/api/endpoints/drive/files/upload_from_url.ts
index 627e81c44e..46cfffb69c 100644
--- a/src/api/endpoints/drive/files/upload_from_url.ts
+++ b/src/api/endpoints/drive/files/upload_from_url.ts
@@ -3,7 +3,7 @@
  */
 import * as URL from 'url';
 const download = require('download');
-import it from 'cafy';
+import $ from 'cafy';
 import { validateFileName } from '../../../models/drive-file';
 import serialize from '../../../serializers/drive-file';
 import create from '../../../common/add-file-to-drive';
@@ -18,7 +18,7 @@ import create from '../../../common/add-file-to-drive';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'url' parameter
 	// TODO: Validate this url
-	const [url, urlErr] = it(params.url).expect.string().required().get();
+	const [url, urlErr] = $(params.url).string().$;
 	if (urlErr) return rej('invalid url param');
 
 	let name = URL.parse(url).pathname.split('/').pop();
@@ -27,7 +27,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Download file
diff --git a/src/api/endpoints/drive/folders.ts b/src/api/endpoints/drive/folders.ts
index 2c5a9ea44a..d49ef0af03 100644
--- a/src/api/endpoints/drive/folders.ts
+++ b/src/api/endpoints/drive/folders.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../models/drive-folder';
 import serialize from '../../serializers/drive-folder';
 
@@ -15,15 +15,15 @@ import serialize from '../../serializers/drive-folder';
  */
 module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
@@ -32,7 +32,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'folder_id' parameter
-	const [folderId = null, folderIdErr] = it(params.folder_id).expect.nullable.id().get();
+	const [folderId = null, folderIdErr] = $(params.folder_id).optional.nullable.id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Construct query
diff --git a/src/api/endpoints/drive/folders/create.ts b/src/api/endpoints/drive/folders/create.ts
index 9d4b530924..8c875db164 100644
--- a/src/api/endpoints/drive/folders/create.ts
+++ b/src/api/endpoints/drive/folders/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../../models/drive-folder';
 import { isValidFolderName } from '../../../models/drive-folder';
 import serialize from '../../../serializers/drive-folder';
@@ -16,11 +16,11 @@ import event from '../../../event';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'name' parameter
-    const [name = '無題のフォルダー', nameErr] = it(params.name).expect.string().validate(isValidFolderName).get();
+	const [name = '無題のフォルダー', nameErr] = $(params.name).optional.string().pipe(isValidFolderName).$;
 	if (nameErr) return rej('invalid name param');
 
 	// Get 'parent_id' parameter
-	const [parentId = null, parentIdErr] = it(params.parent_id).expect.nullable.id().get();
+	const [parentId = null, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
 	if (parentIdErr) return rej('invalid parent_id param');
 
 	// If the parent folder is specified
diff --git a/src/api/endpoints/drive/folders/find.ts b/src/api/endpoints/drive/folders/find.ts
index 0877f46bc9..cdf055839a 100644
--- a/src/api/endpoints/drive/folders/find.ts
+++ b/src/api/endpoints/drive/folders/find.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../../models/drive-folder';
 import serialize from '../../../serializers/drive-folder';
 
@@ -14,11 +14,11 @@ import serialize from '../../../serializers/drive-folder';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().required().get();
+	const [name, nameErr] = $(params.name).string().$;
 	if (nameErr) return rej('invalid name param');
 
 	// Get 'parent_id' parameter
-	const [parentId, parentIdErr] = it(params.parent_id).expect.id().get();
+	const [parentId = null, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
 	if (parentIdErr) return rej('invalid parent_id param');
 
 	// Issue query
diff --git a/src/api/endpoints/drive/folders/show.ts b/src/api/endpoints/drive/folders/show.ts
index bd5ef731db..9b1c04ca3c 100644
--- a/src/api/endpoints/drive/folders/show.ts
+++ b/src/api/endpoints/drive/folders/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../../models/drive-folder';
 import serialize from '../../../serializers/drive-folder';
 
@@ -14,7 +14,7 @@ import serialize from '../../../serializers/drive-folder';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = it(params.folder_id).expect.id().required().get();
+	const [folderId, folderIdErr] = $(params.folder_id).id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Get folder
diff --git a/src/api/endpoints/drive/folders/update.ts b/src/api/endpoints/drive/folders/update.ts
index 815f458756..eec2757878 100644
--- a/src/api/endpoints/drive/folders/update.ts
+++ b/src/api/endpoints/drive/folders/update.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFolder from '../../../models/drive-folder';
 import { isValidFolderName } from '../../../models/drive-folder';
 import serialize from '../../../serializers/drive-file';
@@ -16,7 +16,7 @@ import event from '../../../event';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'folder_id' parameter
-	const [folderId, folderIdErr] = it(params.folder_id).expect.id().required().get();
+	const [folderId, folderIdErr] = $(params.folder_id).id().$;
 	if (folderIdErr) return rej('invalid folder_id param');
 
 	// Fetch folder
@@ -31,12 +31,12 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().validate(isValidFolderName).get();
+	const [name, nameErr] = $(params.name).optional.string().pipe(isValidFolderName).$;
 	if (nameErr) return rej('invalid name param');
 	if (name) folder.name = name;
 
 	// Get 'parent_id' parameter
-	const [parentId, parentIdErr] = it(params.parent_id).expect.nullable.id().get();
+	const [parentId, parentIdErr] = $(params.parent_id).optional.nullable.id().$;
 	if (parentIdErr) return rej('invalid parent_id param');
 	if (parentId !== undefined) {
 		if (parentId === null) {
diff --git a/src/api/endpoints/drive/stream.ts b/src/api/endpoints/drive/stream.ts
index f5b53680db..32f7ac7e0a 100644
--- a/src/api/endpoints/drive/stream.ts
+++ b/src/api/endpoints/drive/stream.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import DriveFile from '../../models/drive-file';
 import serialize from '../../serializers/drive-file';
 
@@ -14,15 +14,15 @@ import serialize from '../../serializers/drive-file';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
@@ -31,7 +31,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'type' parameter
-	const [type, typeErr] = it(params.type).expect.string().match(/^[a-zA-Z\/\-\*]+$/).get();
+	const [type, typeErr] = $(params.type).optional.string().match(/^[a-zA-Z\/\-\*]+$/).$;
 	if (typeErr) return rej('invalid type param');
 
 	// Construct query
@@ -51,7 +51,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 			$lt: maxId
 		};
 	}
-	if (type !== null) {
+	if (type) {
 		query.type = new RegExp(`^${type.replace(/\*/g, '.+?')}$`);
 	}
 
diff --git a/src/api/endpoints/following/create.ts b/src/api/endpoints/following/create.ts
index 28a69844c2..b4a2217b16 100644
--- a/src/api/endpoints/following/create.ts
+++ b/src/api/endpoints/following/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import Following from '../../models/following';
 import notify from '../../common/notify';
@@ -19,7 +19,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id!').get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// 自分自身
diff --git a/src/api/endpoints/following/delete.ts b/src/api/endpoints/following/delete.ts
index f8c4541552..aa1639ef6c 100644
--- a/src/api/endpoints/following/delete.ts
+++ b/src/api/endpoints/following/delete.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import Following from '../../models/following';
 import event from '../../event';
@@ -18,7 +18,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	const follower = user;
 
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id!').get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Check if the followee is yourself
diff --git a/src/api/endpoints/i/authorized_apps.ts b/src/api/endpoints/i/authorized_apps.ts
index 16de70ba31..807ca5b1e7 100644
--- a/src/api/endpoints/i/authorized_apps.ts
+++ b/src/api/endpoints/i/authorized_apps.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import AccessToken from '../../models/access-token';
 import serialize from '../../serializers/app';
 
@@ -14,15 +14,15 @@ import serialize from '../../serializers/app';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'sort' parameter
-	const [sort = 'desc', sortError] = it(params.sort).expect.string().or('desc asc').get();
+	const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
 	if (sortError) return rej('invalid sort param');
 
 	// Get tokens
diff --git a/src/api/endpoints/i/favorites.ts b/src/api/endpoints/i/favorites.ts
index 208509ec37..a66eaa7546 100644
--- a/src/api/endpoints/i/favorites.ts
+++ b/src/api/endpoints/i/favorites.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Favorite from '../../models/favorite';
 import serialize from '../../serializers/post';
 
@@ -14,15 +14,15 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'sort' parameter
-	const [sort = 'desc', sortError] = it(params.sort).expect.string().or('desc asc').get();
+	const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
 	if (sortError) return rej('invalid sort param');
 
 	// Get favorites
diff --git a/src/api/endpoints/i/notifications.ts b/src/api/endpoints/i/notifications.ts
index c2b36686a1..5575fb7412 100644
--- a/src/api/endpoints/i/notifications.ts
+++ b/src/api/endpoints/i/notifications.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Notification from '../../models/notification';
 import serialize from '../../serializers/notification';
 import getFriends from '../../common/get-friends';
@@ -16,27 +16,27 @@ import getFriends from '../../common/get-friends';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'following' parameter
 	const [following = false, followingError] =
-		it(params.following).expect.boolean().get();
+		$(params.following).optional.boolean().$;
 	if (followingError) return rej('invalid following param');
 
 	// Get 'mark_as_read' parameter
-	const [markAsRead = true, markAsReadErr] = it(params.mark_as_read).expect.boolean().get();
+	const [markAsRead = true, markAsReadErr] = $(params.mark_as_read).optional.boolean().$;
 	if (markAsReadErr) return rej('invalid mark_as_read param');
 
 	// Get 'type' parameter
-	const [type, typeErr] = it(params.type).expect.array().unique().allString().get();
+	const [type, typeErr] = $(params.type).optional.array('string').unique().$;
 	if (typeErr) return rej('invalid type param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
@@ -53,7 +53,7 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	};
 
 	if (following) {
-		// ID list of the user itself and other users who the user follows
+		// ID list of the user $self and other users who the user follows
 		const followingIds = await getFriends(user._id);
 
 		query.notifier_id = {
diff --git a/src/api/endpoints/i/signin_history.ts b/src/api/endpoints/i/signin_history.ts
index 5b5f654eea..1a6e50c7c8 100644
--- a/src/api/endpoints/i/signin_history.ts
+++ b/src/api/endpoints/i/signin_history.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Signin from '../../models/signin';
 import serialize from '../../serializers/signin';
 
@@ -14,15 +14,15 @@ import serialize from '../../serializers/signin';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/i/update.ts b/src/api/endpoints/i/update.ts
index dd5a7dd240..111a4b1909 100644
--- a/src/api/endpoints/i/update.ts
+++ b/src/api/endpoints/i/update.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import { isValidName, isValidDescription, isValidLocation, isValidBirthday } from '../../models/user';
 import serialize from '../../serializers/user';
@@ -19,32 +19,32 @@ import config from '../../../conf';
  */
 module.exports = async (params, user, _, isSecure) => new Promise(async (res, rej) => {
 	// Get 'name' parameter
-	const [name, nameErr] = it(params.name).expect.string().validate(isValidName).get();
+	const [name, nameErr] = $(params.name).optional.string().pipe(isValidName).$;
 	if (nameErr) return rej('invalid name param');
 	if (name) user.name = name;
 
 	// Get 'description' parameter
-	const [description, descriptionErr] = it(params.description).expect.nullable.string().validate(isValidDescription).get();
+	const [description, descriptionErr] = $(params.description).optional.nullable.string().pipe(isValidDescription).$;
 	if (descriptionErr) return rej('invalid description param');
 	if (description !== undefined) user.description = description;
 
 	// Get 'location' parameter
-	const [location, locationErr] = it(params.location).expect.nullable.string().validate(isValidLocation).get();
+	const [location, locationErr] = $(params.location).optional.nullable.string().pipe(isValidLocation).$;
 	if (locationErr) return rej('invalid location param');
 	if (location !== undefined) user.profile.location = location;
 
 	// Get 'birthday' parameter
-	const [birthday, birthdayErr] = it(params.birthday).expect.nullable.string().validate(isValidBirthday).get();
+	const [birthday, birthdayErr] = $(params.birthday).optional.nullable.string().pipe(isValidBirthday).$;
 	if (birthdayErr) return rej('invalid birthday param');
 	if (birthday !== undefined) user.profile.birthday = birthday;
 
 	// Get 'avatar_id' parameter
-	const [avatarId, avatarIdErr] = it(params.avatar_id).expect.id().get();
+	const [avatarId, avatarIdErr] = $(params.avatar_id).optional.id().$;
 	if (avatarIdErr) return rej('invalid avatar_id param');
 	if (avatarId) user.avatar_id = avatarId;
 
 	// Get 'banner_id' parameter
-	const [bannerId, bannerIdErr] = it(params.banner_id).expect.id().get();
+	const [bannerId, bannerIdErr] = $(params.banner_id).optional.id().$;
 	if (bannerIdErr) return rej('invalid banner_id param');
 	if (bannerId) user.banner_id = bannerId;
 
diff --git a/src/api/endpoints/messaging/history.ts b/src/api/endpoints/messaging/history.ts
index 68f46ca3dc..5f7c9276dd 100644
--- a/src/api/endpoints/messaging/history.ts
+++ b/src/api/endpoints/messaging/history.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import History from '../../models/messaging-history';
 import serialize from '../../serializers/messaging-message';
 
@@ -14,7 +14,7 @@ import serialize from '../../serializers/messaging-message';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get history
diff --git a/src/api/endpoints/messaging/messages.ts b/src/api/endpoints/messaging/messages.ts
index 7adfa63611..b3a5c57f6c 100644
--- a/src/api/endpoints/messaging/messages.ts
+++ b/src/api/endpoints/messaging/messages.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Message from '../../models/messaging-message';
 import User from '../../models/user';
 import serialize from '../../serializers/messaging-message';
@@ -17,7 +17,7 @@ import { publishMessagingStream } from '../../event';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [recipientId, recipientIdErr] = it(params.user_id).expect.id().required().get();
+	const [recipientId, recipientIdErr] = $(params.user_id).id().$;
 	if (recipientIdErr) return rej('invalid user_id param');
 
 	// Fetch recipient
@@ -34,19 +34,19 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'mark_as_read' parameter
-	const [markAsRead = true, markAsReadErr] = it(params.mark_as_read).expect.boolean().get();
+	const [markAsRead = true, markAsReadErr] = $(params.mark_as_read).optional.boolean().$;
 	if (markAsReadErr) return rej('invalid mark_as_read param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/messaging/messages/create.ts b/src/api/endpoints/messaging/messages/create.ts
index dc3556da0d..05f9cda4cb 100644
--- a/src/api/endpoints/messaging/messages/create.ts
+++ b/src/api/endpoints/messaging/messages/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Message from '../../../models/messaging-message';
 import { isValidText } from '../../../models/messaging-message';
 import History from '../../../models/messaging-history';
@@ -21,7 +21,7 @@ import config from '../../../../conf';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [recipientId, recipientIdErr] = it(params.user_id).expect.id().required().get();
+	const [recipientId, recipientIdErr] = $(params.user_id).id().$;
 	if (recipientIdErr) return rej('invalid user_id param');
 
 	// Myself
@@ -43,11 +43,11 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'text' parameter
-	const [text, textErr] = it(params.text).expect.string().validate(isValidText).get();
+	const [text, textErr] = $(params.text).optional.string().pipe(isValidText).$;
 	if (textErr) return rej('invalid text');
 
 	// Get 'file_id' parameter
-	const [fileId, fileIdErr] = it(params.file_id).expect.id().get();
+	const [fileId, fileIdErr] = $(params.file_id).optional.id().$;
 	if (fileIdErr) return rej('invalid file_id param');
 
 	let file = null;
diff --git a/src/api/endpoints/my/apps.ts b/src/api/endpoints/my/apps.ts
index 0aee1c031a..eb9c758768 100644
--- a/src/api/endpoints/my/apps.ts
+++ b/src/api/endpoints/my/apps.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import App from '../../models/app';
 import serialize from '../../serializers/app';
 
@@ -14,11 +14,11 @@ import serialize from '../../serializers/app';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	const query = {
diff --git a/src/api/endpoints/notifications/mark_as_read.ts b/src/api/endpoints/notifications/mark_as_read.ts
index 9dc7c20646..5cce33e850 100644
--- a/src/api/endpoints/notifications/mark_as_read.ts
+++ b/src/api/endpoints/notifications/mark_as_read.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Notification from '../../models/notification';
 import serialize from '../../serializers/notification';
 import event from '../../event';
@@ -14,7 +14,7 @@ import event from '../../event';
  * @return {Promise<any>}
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
-	const [notificationId, notificationIdErr] = it(params.notification_id).expect.id().required().get();
+	const [notificationId, notificationIdErr] = $(params.notification_id).id().$;
 	if (notificationIdErr) return rej('invalid notification_id param');
 
 	// Get notification
diff --git a/src/api/endpoints/posts.ts b/src/api/endpoints/posts.ts
index 2e8ef6c6da..999d63a86e 100644
--- a/src/api/endpoints/posts.ts
+++ b/src/api/endpoints/posts.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../models/post';
 import serialize from '../serializers/post';
 
@@ -13,23 +13,23 @@ import serialize from '../serializers/post';
  */
 module.exports = (params) => new Promise(async (res, rej) => {
 	// Get 'include_replies' parameter
-	const [includeReplies = true, includeRepliesErr] = it(params.include_replies).expect.boolean().get();
+	const [includeReplies = true, includeRepliesErr] = $(params.include_replies).optional.boolean().$;
 	if (includeRepliesErr) return rej('invalid include_replies param');
 
 	// Get 'include_reposts' parameter
-	const [includeReposts = true, includeRepostsErr] = it(params.include_reposts).expect.boolean().get();
+	const [includeReposts = true, includeRepostsErr] = $(params.include_reposts).optional.boolean().$;
 	if (includeRepostsErr) return rej('invalid include_reposts param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/posts/context.ts b/src/api/endpoints/posts/context.ts
index 03f5a95800..cd5f15f481 100644
--- a/src/api/endpoints/posts/context.ts
+++ b/src/api/endpoints/posts/context.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import serialize from '../../serializers/post';
 
@@ -14,15 +14,15 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Lookup post
diff --git a/src/api/endpoints/posts/create.ts b/src/api/endpoints/posts/create.ts
index 7f952e83be..4cb60705af 100644
--- a/src/api/endpoints/posts/create.ts
+++ b/src/api/endpoints/posts/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 const parse = require('../../../common/text');
 import Post from '../../models/post';
 import { isValidText } from '../../models/post';
@@ -23,11 +23,11 @@ import config from '../../../conf';
  */
 module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	// Get 'text' parameter
-	const [text, textErr] = it(params.text).must.be.a.string().validate(isValidText).get();
+	const [text, textErr] = $(params.text).optional.string().pipe(isValidText).$;
 	if (textErr) return rej('invalid text');
 
 	// Get 'media_ids' parameter
-	const [mediaIds, mediaIdsErr] = it(params.media_ids).must.be.an.array().unique().range(1, 4).get();
+	const [mediaIds, mediaIdsErr] = $(params.media_ids).optional.array('id').unique().range(1, 4).$;
 	if (mediaIdsErr) return rej('invalid media_ids');
 
 	let files = [];
@@ -36,8 +36,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 		// forEach だと途中でエラーなどがあっても return できないので
 		// 敢えて for を使っています。
 		for (let i = 0; i < mediaIds.length; i++) {
-			const [mediaId, mediaIdErr] = it(mediaIds[i]).must.be.an.id().required().get();
-			if (mediaIdErr) return rej('invalid media id');
+			const mediaId = mediaIds[i];
 
 			// Fetch file
 			// SELECT _id
@@ -59,7 +58,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'repost_id' parameter
-	const [repostId, repostIdErr] = it(params.repost_id).must.be.an.id().get();
+	const [repostId, repostIdErr] = $(params.repost_id).optional.id().$;
 	if (repostIdErr) return rej('invalid repost_id');
 
 	let repost = null;
@@ -101,7 +100,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'in_reply_to_post_id' parameter
-	const [inReplyToPostId, inReplyToPostIdErr] = it(params.reply_to_id, 'id').get();
+	const [inReplyToPostId, inReplyToPostIdErr] = $(params.reply_to_id).optional.id().$;
 	if (inReplyToPostIdErr) return rej('invalid in_reply_to_post_id');
 
 	let inReplyToPost = null;
@@ -122,37 +121,24 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'poll' parameter
-	const [_poll, pollErr] = it(params.poll, 'object').get();
+	const [poll, pollErr] = $(params.poll).optional.object()
+		.have('choices', $().array('string')
+			.unique()
+			.range(2, 10)
+			.each(c => c.length > 0 && c.length < 50))
+		.$;
 	if (pollErr) return rej('invalid poll');
 
-	let poll = null;
-	if (_poll !== undefined) {
-		const [pollChoices, pollChoicesErr] =
-			it(params.poll.choices).expect.array()
-				.required()
-				.unique()
-				.allString()
-				.range(2, 10)
-				.validate(choices => !choices.some(choice => {
-					if (typeof choice != 'string') return true;
-					if (choice.trim().length == 0) return true;
-					if (choice.trim().length > 50) return true;
-					return false;
-				}))
-				.get();
-		if (pollChoicesErr) return rej('invalid poll choices');
-
-		_poll.choices = pollChoices.map((choice, i) => ({
+	if (poll) {
+		(poll as any).choices = (poll as any).choices.map((choice, i) => ({
 			id: i, // IDを付与
 			text: choice.trim(),
 			votes: 0
 		}));
-
-		poll = _poll;
 	}
 
 	// テキストが無いかつ添付ファイルが無いかつRepostも無いかつ投票も無かったらエラー
-	if (text === undefined && files === null && repost === null && poll === null) {
+	if (text === undefined && files === null && repost === null && poll === undefined) {
 		return rej('text, media_ids, repost_id or poll is required');
 	}
 
@@ -162,7 +148,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 		media_ids: files ? files.map(file => file._id) : undefined,
 		reply_to_id: inReplyToPost ? inReplyToPost._id : undefined,
 		repost_id: repost ? repost._id : undefined,
-		poll: poll ? poll : undefined,
+		poll: poll,
 		text: text,
 		user_id: user._id,
 		app_id: app ? app._id : null
@@ -235,7 +221,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 		addMention(inReplyToPost.user_id, 'reply');
 	}
 
-	// If it is repost
+	// If $ is repost
 	if (repost) {
 		// Notify
 		const type = text ? 'quote' : 'repost';
@@ -243,7 +229,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 			post_id: post._id
 		});
 
-		// If it is quote repost
+		// If $ is quote repost
 		if (text) {
 			// Add mention
 			addMention(repost.user_id, 'quote');
diff --git a/src/api/endpoints/posts/favorites/create.ts b/src/api/endpoints/posts/favorites/create.ts
index 96edf0eb27..f9dee271b5 100644
--- a/src/api/endpoints/posts/favorites/create.ts
+++ b/src/api/endpoints/posts/favorites/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Favorite from '../../../models/favorite';
 import Post from '../../../models/post';
 
@@ -14,7 +14,7 @@ import Post from '../../../models/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get favoritee
diff --git a/src/api/endpoints/posts/favorites/delete.ts b/src/api/endpoints/posts/favorites/delete.ts
index 5179fad9a5..c4fe7d3234 100644
--- a/src/api/endpoints/posts/favorites/delete.ts
+++ b/src/api/endpoints/posts/favorites/delete.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Favorite from '../../../models/favorite';
 import Post from '../../../models/post';
 
@@ -14,7 +14,7 @@ import Post from '../../../models/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get favoritee
diff --git a/src/api/endpoints/posts/likes.ts b/src/api/endpoints/posts/likes.ts
index 23933237a7..29aff1de38 100644
--- a/src/api/endpoints/posts/likes.ts
+++ b/src/api/endpoints/posts/likes.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import Like from '../../models/like';
 import serialize from '../../serializers/user';
@@ -15,19 +15,19 @@ import serialize from '../../serializers/user';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'sort' parameter
-	const [sort = 'desc', sortError] = it(params.sort).expect.string().or('desc asc').get();
+	const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
 	if (sortError) return rej('invalid sort param');
 
 	// Lookup post
diff --git a/src/api/endpoints/posts/likes/create.ts b/src/api/endpoints/posts/likes/create.ts
index db8b6d0b20..3a7650dead 100644
--- a/src/api/endpoints/posts/likes/create.ts
+++ b/src/api/endpoints/posts/likes/create.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Like from '../../../models/like';
 import Post from '../../../models/post';
 import User from '../../../models/user';
@@ -16,7 +16,7 @@ import notify from '../../../common/notify';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get likee
diff --git a/src/api/endpoints/posts/likes/delete.ts b/src/api/endpoints/posts/likes/delete.ts
index 8d9fe273db..d90f2937e0 100644
--- a/src/api/endpoints/posts/likes/delete.ts
+++ b/src/api/endpoints/posts/likes/delete.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Like from '../../../models/like';
 import Post from '../../../models/post';
 import User from '../../../models/user';
@@ -16,7 +16,7 @@ import User from '../../../models/user';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get likee
diff --git a/src/api/endpoints/posts/mentions.ts b/src/api/endpoints/posts/mentions.ts
index 677df52b28..0ebe8be503 100644
--- a/src/api/endpoints/posts/mentions.ts
+++ b/src/api/endpoints/posts/mentions.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import getFriends from '../../common/get-friends';
 import serialize from '../../serializers/post';
@@ -16,19 +16,19 @@ import serialize from '../../serializers/post';
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'following' parameter
 	const [following = false, followingError] =
-		it(params.following).expect.boolean().get();
+		$(params.following).optional.boolean().$;
 	if (followingError) return rej('invalid following param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/posts/polls/vote.ts b/src/api/endpoints/posts/polls/vote.ts
index 04e380807f..e345497905 100644
--- a/src/api/endpoints/posts/polls/vote.ts
+++ b/src/api/endpoints/posts/polls/vote.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Vote from '../../../models/poll-vote';
 import Post from '../../../models/post';
 import notify from '../../../common/notify';
@@ -15,7 +15,7 @@ import notify from '../../../common/notify';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get votee
@@ -33,10 +33,9 @@ module.exports = (params, user) => new Promise(async (res, rej) => {
 
 	// Get 'choice' parameter
 	const [choice, choiceError] =
-		it(params.choice).expect.string()
-			.required()
-			.validate(c => post.poll.choices.some(x => x.id == c))
-			.get();
+		$(params.choice).string()
+			.pipe(c => post.poll.choices.some(x => x.id == c))
+			.$;
 	if (choiceError) return rej('invalid choice param');
 
 	// if already voted
diff --git a/src/api/endpoints/posts/replies.ts b/src/api/endpoints/posts/replies.ts
index 4516dce15c..89f4d99841 100644
--- a/src/api/endpoints/posts/replies.ts
+++ b/src/api/endpoints/posts/replies.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import serialize from '../../serializers/post';
 
@@ -14,19 +14,19 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'sort' parameter
-	const [sort = 'desc', sortError] = it(params.sort).expect.string().or('desc asc').get();
+	const [sort = 'desc', sortError] = $(params.sort).optional.string().or('desc asc').$;
 	if (sortError) return rej('invalid sort param');
 
 	// Lookup post
diff --git a/src/api/endpoints/posts/reposts.ts b/src/api/endpoints/posts/reposts.ts
index 5098d5af81..b701ff7574 100644
--- a/src/api/endpoints/posts/reposts.ts
+++ b/src/api/endpoints/posts/reposts.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import serialize from '../../serializers/post';
 
@@ -14,19 +14,19 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/posts/search.ts b/src/api/endpoints/posts/search.ts
index 04b845bc3a..b434f64342 100644
--- a/src/api/endpoints/posts/search.ts
+++ b/src/api/endpoints/posts/search.ts
@@ -2,7 +2,7 @@
  * Module dependencies
  */
 import * as mongo from 'mongodb';
-import it from 'cafy';
+import $ from 'cafy';
 const escapeRegexp = require('escape-regexp');
 import Post from '../../models/post';
 import serialize from '../../serializers/post';
@@ -17,18 +17,18 @@ import config from '../../../conf';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'query' parameter
-	const [query, queryError] = it(params.query).expect.string().required().trim().validate(x => x != '').get();
+	const [query, queryError] = $(params.query).string().pipe(x => x != '').$;
 	if (queryError) return rej('invalid query param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'max' parameter
-	const [max = 10, maxErr] = it(params.max).expect.number().range(1, 30).get();
+	const [max = 10, maxErr] = $(params.max).optional.number().range(1, 30).$;
 	if (maxErr) return rej('invalid max param');
 
-	// If Elasticsearch is available, search by it
+	// If Elasticsearch is available, search by $
 	// If not, search by MongoDB
 	(config.elasticsearch.enable ? byElasticsearch : byNative)
 		(res, rej, me, query, offset, max);
diff --git a/src/api/endpoints/posts/show.ts b/src/api/endpoints/posts/show.ts
index e0bed903b4..5bfe4f6605 100644
--- a/src/api/endpoints/posts/show.ts
+++ b/src/api/endpoints/posts/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import serialize from '../../serializers/post';
 
@@ -14,7 +14,7 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user) => new Promise(async (res, rej) => {
 	// Get 'post_id' parameter
-	const [postId, postIdErr] = it(params.post_id, 'id!').get();
+	const [postId, postIdErr] = $(params.post_id).id().$;
 	if (postIdErr) return rej('invalid post_id param');
 
 	// Get post
diff --git a/src/api/endpoints/posts/timeline.ts b/src/api/endpoints/posts/timeline.ts
index 02fdf4a17c..314e992344 100644
--- a/src/api/endpoints/posts/timeline.ts
+++ b/src/api/endpoints/posts/timeline.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import getFriends from '../../common/get-friends';
 import serialize from '../../serializers/post';
@@ -16,15 +16,15 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, user, app) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
@@ -32,7 +32,7 @@ module.exports = (params, user, app) => new Promise(async (res, rej) => {
 		return rej('cannot set since_id and max_id');
 	}
 
-	// ID list of the user itself and other users who the user follows
+	// ID list of the user $self and other users who the user follows
 	const followingIds = await getFriends(user._id);
 
 	// Construct query
diff --git a/src/api/endpoints/username/available.ts b/src/api/endpoints/username/available.ts
index 309e289d06..3be7bcba32 100644
--- a/src/api/endpoints/username/available.ts
+++ b/src/api/endpoints/username/available.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import { validateUsername } from '../../models/user';
 
@@ -13,7 +13,7 @@ import { validateUsername } from '../../models/user';
  */
 module.exports = async (params) => new Promise(async (res, rej) => {
 	// Get 'username' parameter
-	const [username, usernameError] = it(params.username).expect.string().required().trim().validate(validateUsername).get();
+	const [username, usernameError] = $(params.username).string().pipe(validateUsername).$;
 	if (usernameError) return rej('invalid username param');
 
 	// Get exist
diff --git a/src/api/endpoints/users.ts b/src/api/endpoints/users.ts
index 6b12c3072e..134f262fb1 100644
--- a/src/api/endpoints/users.ts
+++ b/src/api/endpoints/users.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../models/user';
 import serialize from '../serializers/user';
 
@@ -14,15 +14,15 @@ import serialize from '../serializers/user';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/users/followers.ts b/src/api/endpoints/users/followers.ts
index 1b032245c8..4905323ba5 100644
--- a/src/api/endpoints/users/followers.ts
+++ b/src/api/endpoints/users/followers.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import Following from '../../models/following';
 import serialize from '../../serializers/user';
@@ -16,19 +16,19 @@ import getFriends from '../../common/get-friends';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id!').get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Get 'iknow' parameter
-	const [iknow = false, iknowErr] = it(params.iknow).expect.boolean().get();
+	const [iknow = false, iknowErr] = $(params.iknow).optional.boolean().$;
 	if (iknowErr) return rej('invalid iknow param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'cursor' parameter
-	const [cursor = null, cursorErr] = it(params.cursor).expect.id().get();
+	const [cursor = null, cursorErr] = $(params.cursor).optional.id().$;
 	if (cursorErr) return rej('invalid cursor param');
 
 	// Lookup user
diff --git a/src/api/endpoints/users/following.ts b/src/api/endpoints/users/following.ts
index 8eb175970b..dc2ff49bbe 100644
--- a/src/api/endpoints/users/following.ts
+++ b/src/api/endpoints/users/following.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import Following from '../../models/following';
 import serialize from '../../serializers/user';
@@ -16,19 +16,19 @@ import getFriends from '../../common/get-friends';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id!').get();
+	const [userId, userIdErr] = $(params.user_id).id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Get 'iknow' parameter
-	const [iknow = false, iknowErr] = it(params.iknow).expect.boolean().get();
+	const [iknow = false, iknowErr] = $(params.iknow).optional.boolean().$;
 	if (iknowErr) return rej('invalid iknow param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'cursor' parameter
-	const [cursor = null, cursorErr] = it(params.cursor).expect.id().get();
+	const [cursor = null, cursorErr] = $(params.cursor).optional.id().$;
 	if (cursorErr) return rej('invalid cursor param');
 
 	// Lookup user
diff --git a/src/api/endpoints/users/posts.ts b/src/api/endpoints/users/posts.ts
index 7ac9f78237..e37b660773 100644
--- a/src/api/endpoints/users/posts.ts
+++ b/src/api/endpoints/users/posts.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import Post from '../../models/post';
 import User from '../../models/user';
 import serialize from '../../serializers/post';
@@ -15,11 +15,11 @@ import serialize from '../../serializers/post';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id').get();
+	const [userId, userIdErr] = $(params.user_id).optional.id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Get 'username' parameter
-	const [username, usernameErr] = it(params.username, 'string').get();
+	const [username, usernameErr] = $(params.username).optional.string().$;
 	if (usernameErr) return rej('invalid username param');
 
 	if (userId === undefined && username === undefined) {
@@ -27,23 +27,23 @@ module.exports = (params, me) => new Promise(async (res, rej) => {
 	}
 
 	// Get 'include_replies' parameter
-	const [includeReplies = true, includeRepliesErr] = it(params.include_replies).expect.boolean().get();
+	const [includeReplies = true, includeRepliesErr] = $(params.include_replies).optional.boolean().$;
 	if (includeRepliesErr) return rej('invalid include_replies param');
 
 	// Get 'with_media' parameter
-	const [withMedia = false, withMediaErr] = it(params.with_media).expect.boolean().get();
+	const [withMedia = false, withMediaErr] = $(params.with_media).optional.boolean().$;
 	if (withMediaErr) return rej('invalid with_media param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'since_id' parameter
-	const [sinceId, sinceIdErr] = it(params.since_id).expect.id().get();
+	const [sinceId, sinceIdErr] = $(params.since_id).optional.id().$;
 	if (sinceIdErr) return rej('invalid since_id param');
 
 	// Get 'max_id' parameter
-	const [maxId, maxIdErr] = it(params.max_id).expect.id().get();
+	const [maxId, maxIdErr] = $(params.max_id).optional.id().$;
 	if (maxIdErr) return rej('invalid max_id param');
 
 	// Check if both of since_id and max_id is specified
diff --git a/src/api/endpoints/users/recommendation.ts b/src/api/endpoints/users/recommendation.ts
index a0fb6613c6..7f5e0b5f5c 100644
--- a/src/api/endpoints/users/recommendation.ts
+++ b/src/api/endpoints/users/recommendation.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import serialize from '../../serializers/user';
 import getFriends from '../../common/get-friends';
@@ -15,14 +15,14 @@ import getFriends from '../../common/get-friends';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
-	// ID list of the user itself and other users who the user follows
+	// ID list of the user $self and other users who the user follows
 	const followingIds = await getFriends(me._id);
 
 	const users = await User
diff --git a/src/api/endpoints/users/search.ts b/src/api/endpoints/users/search.ts
index 8be6a4dc8c..a3f2fb796d 100644
--- a/src/api/endpoints/users/search.ts
+++ b/src/api/endpoints/users/search.ts
@@ -2,7 +2,7 @@
  * Module dependencies
  */
 import * as mongo from 'mongodb';
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import serialize from '../../serializers/user';
 import config from '../../../conf';
@@ -17,18 +17,18 @@ const escapeRegexp = require('escape-regexp');
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'query' parameter
-	const [query, queryError] = it(params.query).expect.string().required().trim().validate(x => x != '').get();
+	const [query, queryError] = $(params.query).string().pipe(x => x != '').$;
 	if (queryError) return rej('invalid query param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'max' parameter
-	const [max = 10, maxErr] = it(params.max).expect.number().range(1, 30).get();
+	const [max = 10, maxErr] = $(params.max).optional.number().range(1, 30).$;
 	if (maxErr) return rej('invalid max param');
 
-	// If Elasticsearch is available, search by it
+	// If Elasticsearch is available, search by $
 	// If not, search by MongoDB
 	(config.elasticsearch.enable ? byElasticsearch : byNative)
 		(res, rej, me, query, offset, max);
diff --git a/src/api/endpoints/users/search_by_username.ts b/src/api/endpoints/users/search_by_username.ts
index b3193a4956..4d7a6e05b8 100644
--- a/src/api/endpoints/users/search_by_username.ts
+++ b/src/api/endpoints/users/search_by_username.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import { validateUsername } from '../../models/user';
 import serialize from '../../serializers/user';
@@ -15,15 +15,15 @@ import serialize from '../../serializers/user';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'query' parameter
-	const [query, queryError] = it(params.query).expect.string().required().trim().validate(validateUsername).get();
+	const [query, queryError] = $(params.query).string().pipe(validateUsername).$;
 	if (queryError) return rej('invalid query param');
 
 	// Get 'offset' parameter
-	const [offset = 0, offsetErr] = it(params.offset).expect.number().min(0).get();
+	const [offset = 0, offsetErr] = $(params.offset).optional.number().min(0).$;
 	if (offsetErr) return rej('invalid offset param');
 
 	// Get 'limit' parameter
-	const [limit = 10, limitErr] = it(params.limit).expect.number().range(1, 100).get();
+	const [limit = 10, limitErr] = $(params.limit).optional.number().range(1, 100).$;
 	if (limitErr) return rej('invalid limit param');
 
 	const users = await User
diff --git a/src/api/endpoints/users/show.ts b/src/api/endpoints/users/show.ts
index 897e777fb6..8e74b0fe3f 100644
--- a/src/api/endpoints/users/show.ts
+++ b/src/api/endpoints/users/show.ts
@@ -1,7 +1,7 @@
 /**
  * Module dependencies
  */
-import it from 'cafy';
+import $ from 'cafy';
 import User from '../../models/user';
 import serialize from '../../serializers/user';
 
@@ -14,11 +14,11 @@ import serialize from '../../serializers/user';
  */
 module.exports = (params, me) => new Promise(async (res, rej) => {
 	// Get 'user_id' parameter
-	const [userId, userIdErr] = it(params.user_id, 'id').get();
+	const [userId, userIdErr] = $(params.user_id).optional.id().$;
 	if (userIdErr) return rej('invalid user_id param');
 
 	// Get 'username' parameter
-	const [username, usernameErr] = it(params.username, 'string').get();
+	const [username, usernameErr] = $(params.username).optional.string().$;
 	if (usernameErr) return rej('invalid username param');
 
 	if (userId === undefined && username === undefined) {