Я уже довольно давно пытаюсь изучить NodeJS. Кажется, что все книги и учебные пособия следуют похожему шаблону структурирования их кода. Пример -
const express = require('express');
const app = express();
app.set('view engine','hbs');
app.get('/', (req, res) =>{
res.render('index');
});
app.get('/getName', (req, res) =>{
// Mock DB call to fetch Name
res.render('displayName');
});
app.listen(3000, () => {
console.log("Started server on port : 3000");
});
Как вы можете видеть выше, контроллер / getName выполняет вызов БД, а также возвращает представление. Таким образом, бизнес-логика и операция CRUD выполняются в одном месте.
Я родом из мира JAVA
и там мы делаем это немного по-другому. Например, приложение Spring Boot
будет содержать следующую структуру -
- DTO
- Репозиторий
- Услуги
- Контроллер
Итак, классы controller
являются фактическими конечными точками, которые не выполняют никакой бизнес-логики, но вызывают базовый класс service
для обработки всего этого. Классы service
реализуют бизнес-логику и сохраняют / извлекают данные, необходимые для нее, с помощью классов repository
. Хранилище, с другой стороны, обрабатывает операции CRUD
.
Это казалось нормальным способом разработки программного обеспечения. Учитывая, что каждый класс имеет свои определенные роли, становится действительно легко обрабатывать любые изменения.
Я понимаю, что NodeJs
является динамическим, но -
1. Есть ли способ выделить функциональность, как мы делаем в Spring
? Если нет,
2. Как структурировать большие проекты с несколькими конечными точками и транзакциями БД.
Привет
РЕДАКТИРОВАТЬ -
Рассмотрим следующий сценарий -
У меня есть требование, в котором мне нужно получить список пользователей из базы данных, состояние которой равно True (предположим, что состояние - это логическое поле в модели).
На Яве -
@Service
public class UserService {
@Autowired
UserDetailRepository userDetailRepository;
@Override
public UserDetail getUserDetail (boolean status) {
UserDetail userDetail = UserDetailRepository .findUserDetailByStatus(status);
return userDetail ;
}
Controller.java -
@GetMapping("/getUserDetails")
public ArrayList<UserDetail> getUserDetail(){
return UserService.getUserDetail(true);
}
Теперь, если требование изменяется, и требуется новая конечная точка, которая возвращает только первые 10 пользовательских данных, статус которых равен true. В этом случае мы можем добавить новый контроллер и ограничить количество возвращаемых результатов до 10. Мы можем использовать один и тот же бизнес-логический класс / класс обслуживания.
*
Controller.java 1064 *
@GetMapping("/getUserDetailsTop10")
public ArrayList<UserDetail> getUserDetail(){
List<UserDetails> users = UserService.getUserDetail(true);
// Filter the list to send top 10
// return users .
}
Если мне нужно реализовать тот же вариант использования в NodeJS, мне придется написать бизнес-логику, чтобы дважды выбрать пользователя -
const express = require('express');
const app = express();
app.set('view engine','hbs');
app.get('/getUserDetails', (req, res) =>{
// Call DB and get users whose status is True
res.send(userdetails);
});
app.get('/getUserDetailsTop10', (req, res) =>{
// Call DB and get users whose status is True
// Filter the returned results and limit the result to 10 values only
res.send(userdetails);
});
app.listen(3000, () => {
console.log("Started server on port : 3000");
});
В лучшем случае я могу абстрагировать эту логику в функцию, которая будет возвращать список пользователей со статусом True, но с другой стороны этот подход не очень масштабируем. Должно быть полное отделение бизнес-логики от контроллера.