хуйу нас не матерятся
Привет, дорогие мои котяточки. Сегодня мы быстренько поднимем API сервер на expressjs и веб-сокетах. Как обычно нет времени объяснять зачем мне это нужно, just do it!
Создаём папку с проектом ("api-express" в моём случае), заходим в неё и инициализируем npm пакет:
npm init -f
Открываем вновь созданный package.json, и добавляем немного зависимостей: express и express-ws.
{
"name": "api-express",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "*",
"express-ws": "*"
}
}
Далее делаем npm install, создаём папку js, файл index.js в корне проекта, и файл app.js в папке js.
Содержимое файла index.js
'use strict'
let app = require('./js/app')
Сейчас от него нужно только инициализировать главный объект. А вот в main.js уже создаём наш expressjs сервер:
'use strict'
const express = require('express')
let app = express()
let expressWs = require('express-ws')(app)
app.ws('/', function(ws, req, next) {
ws.on('message', function(msg) {
console.log('msg:', msg)
})
})
app.listen(3000, function() {
console.log('Started, port: 3000')
})
После этого можем запустить наш сервер:
node index.js
Чтобы проверить, работает ли оно, ставим на гугло-хром плагин "Smart websocket client". Открываем его, вводим адрес ws://localhost:3000 коннектимся. И отправляем любые данные, при этом они должны залогиться в консольке:
Так как в вебсокетах нет http рутов, да и ваще мы получаем просто строку с данными, сам БГ велел использовать json для общения между клиентом и сервером. Но прежде всего давайте напишем небольшую RESTful like документацию на наше api.
1. randomString action
Request:
{
"get": "randomString", # Route
"length": 12345 # stringlength
}
Response:
{
"code": 200, # Response code
"message": "OK", # Response message
"data": "abcde" # Response data
}
2. Error responses
{
"code" : 12345, # Error code
"message" : "Blabla error", # Error message
}
Теперь начинаем воплощать нашу документацию в код. В папке js создаём router.js открываем его и пишем следующий код:
'use strict'
const RandomString = require('./actions/randomString') // Подключаем экшен
const errors = require('./errors')
module.exports = class Router {
constructor() {
this.randomString = new RandomString()
}
parseRequest(str) {
let data = false
try {
data = JSON.parse(str)
} catch(e) {
}
return data
}
go(req, ws, msg) {
let data = this.parseRequest(msg) // Вдруг прилетел неправильный json
if( data ) {
switch( data.get ) {
case 'randomString': // Смотрим, есть ли у нас экшен
this.randomString.response(ws, data)
break
default: // Либо отдаём 404
ws.send( JSON.stringify(errors['404']) )
break
}
} else
ws.send( JSON.stringify(errors['400']) )
}
}
Тут же создаём errors.js:
'use strict'
let errors = {
'400': {
code: 400,
message: 'Bad Request',
description: 'Bad request data'
},
'401': {
code: 401,
message: 'Unauthorized',
description: 'Please authorize first.'
},
'404': {
code: 404,
message: 'Not found',
description: 'Action not found'
},
'500': {
code: 500,
message: 'Internal Server Error',
description: 'Internal Server Error.'
}
}
module.exports = errors
Теперь создаём папку "actions" и в ней randomString.js:
'use strict'
module.exports = class RandomString {
getRandomString(length) {
let text = ''
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
for( let i=0; i < length; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length))
return text
}
response(ws, data) {
if( data.length )
ws.send( JSON.stringify({
code: 200,
message: 'OK',
data: this.getRandomString(data.length)
}) )
else
ws.send( JSON.stringify(errors['400']) )
}
}
Нам осталось немного подправить app.js и всё будет готово:
'use strict'
const express = require('express')
const Router = require('./router')
let router = new Router()
let app = express()
let expressWs = require('express-ws')(app)
app.ws('/', function(ws, req, next) {
ws.on('message', function(msg) {
router.go(req, ws, msg)
})
})
app.listen(3000, function() {
console.log('Started, port: 3000')
})
Проверяем, отправляем неправильный запрос:
Всё нормально, получили в ответ ошибку. Теперь отправляем правильный запрос:
Так же всё ок. В ответ получили код 200 и случайную строку в 12 символов. Заготовка под API сервер готова, теперь можно подключать нормальные экшены.
Архив с проектом: api-express-ws.tar.gz