在快速REST API中使用OOP的最佳方式? [英] Best Way to Use OOP in Express REST API?

查看:159
本文介绍了在快速REST API中使用OOP的最佳方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在进行中,只使用一个节点进行一个项目。这是非常有趣的,但有时候我有点迷失,我想尝试获得理解,因为我困惑,所以我建立正确,不要太淹没。无论如何,这里的问题:



我有使用Express和mysql的REST API。我设置了mysql:



app.js



  //变量,将它们移动到env 
var dbOptions = {
host:config.db_config.host,
user:config.db_config.user,
password:config.db_config.password,
port:config.db_config.port,
数据库:config.db_config.database
};
app.use(myConnection(mysql,dbOptions,'single'));

然后我包含我的路由,传递路由应用程序和日志中间件,以便我们可以使用它们路线:



app.js cont。



  var userRoute =要求( ./路由/ users.js')(应用程序,日志); 
app.use('/ users',userRoute);

实际上有点混乱,但现在我得到它,我必须将它们传递到模块订单让模块获取数据。



然后在我的路由文件中,我想使用一个对象,以便我可以在其他路由中使用相同的功能,但在用户文件为了使用与其他所有使用相同的连接池,或至少不必再次设置连接,我必须通过它的响应和请求?必须有一个更好的方式来做到这一点。这真的很丑陋。以下是



routes / users.js



  var的相关部分User = require('../ controllers / User.js'); 

module.exports =(function(app,log){
var userR = express.Router();

userR.post('/ register' function(req,res){
var email = req.body.email;
var password = req.body.password;
var firstName = req.body.first_name;
var lastName = req.body.last_name;
var userId;

try {
var query;
var status = 200;
var response =' ';

var newUser = {
电子邮件:电子邮件,
密码:密码,
first_name:firstName,
last_name:lastName,
密码:密码
};

var user = new用户(req,res);

user.register(newUser);
...

};



controllers / User.js



  module.exports = function User(req,res){
this.i d = 0;
this.register = function(newUser){

var _this = this;
var deferred = q.defer();
req.getConnection(function(err,connection){
...

我必须有一个这样的模式,我应该能够传递应用程序或某些东西,并且可以访问req.getConnection等。



谢谢。

解决方案

这里有很多事情,但是我会在这个问题上解决。



我的第一个建议是尝试让路由器变得很苗条,没有标签,但我假设你提供的最大的代码片段是你的路由器,有很多当然,如果我这样做,我的路由器会是这样,我假设你正在使用Express 4x。



routes / users.js



  var User = require('../ controllers / user.js'); 
var userRouter = express.Router ();
userRouter.post(/ register,User.register);
module.exports = userRouter;

所以我们在这里做的是消除了对你的应用程序/日志中间件的依赖。



这意味着你的主文件(通常称为app.js)像这样:



app.js



  var userRouter = require  ./routes/users.js'); 
app.use('/ users',userRouter);

这也是您可以放置​​任何您选择的中间件(记录,身体解析,错误处理,等)。



在更高版本的Express中,上述代码实际上将我们的userRouter挂载到/ users。在这种情况下,您将拥有一个/ users / register路由。



所以现在,由于我们已经删除了路由器的一些逻辑,我们必须把它放在某个地方。通常路由器会与控制器通话,让我们来看看:



controllers / user.js



  var User = require(../ models / user.js)
var register = function(req,res,next){
var email = req.body 。电子邮件;
var password = req.body.password;
var firstName = req.body.first_name;
var lastName = req.body.last_name;
var userId;
var params = {
email:email,
password:password,
first_name:firstName,
last_name:lastName,
password:password
};
var newUser = new User(params);

try {
newUser.register();
//做其他事情...
}
};
module.exports = {register:register};

你会注意到的第一件事是我会有一个UserModel文件。通过这样做,我们已经从我们的路由去除了我们的模型对象。比方说,我们有一个新的注册路由(也许其中一个有一个电子邮件+ pw,另一个通过FB注册,我们必须存储不同的东西)。我们应该能够使用我们模型中指定的相同的功能(在这种情况下是user.register),而不必改变一大堆东西!



现在,这里是UserModel可能如下所示:



/models/user.js



  var connection = require(../ lib / connection.js); 
var User = function(params){
this.email = params.email;
// ... etc
};

User.prototype.register = function(newUser){
connection.getConnection(function(error,connection){
//connection.doWhatever();
});
};

module.exports = User;

现在我们终于得到了你的问题的核心。在顶部,您将看到我们有一个连接文件。这就是我们将所有与DB相关的逻辑,如我们的连接池。



/lib/connection.js



  / * 
这将是一些JSON配置,我们会说
var dbOptions = {
host:config.db_config .host,
用户:config.db_config.user,
密码:config.db_config.password,
端口:config.db_config.port,
数据库:config.db_config.database
};

* /
//这取决于你使用的是哪个版本/模块/数据库,但是这里是我看起来像
var MySQL = require(mysql) ;
var config = require(../ config / db.json);
connectionPool = MySQL.createPool({host:config.db_config.host,...});

var getConnection = function(done){
connectionPool.getConnection(done);
};

module.exports = {getConnection:getConnection};

总而言之,我们现在只是简单地将我们的连接短连接模块在我们所在的模型文件中,请求连接,并做任何我们需要的处理。还要注意,你必须将连接释放到游泳池中,但是我会把它当作一个练习。



此外,我通常会写CoffeeScript,所以请原谅任何小错误。如果您需要进一步澄清,请告知我。



干杯,
Brennan


I'm going all in and doing a project using only node. It's been a lot of fun, but sometimes I get a little lost in it and I want to try to gain understanding as I get confused so I build it correctly and don't get too overwhelmed. Anyway, here's the problem:

I have REST API that's using Express and mysql. I set up mysql:

app.js

//Variables, move these to env
var dbOptions = {
    host: config.db_config.host,
    user: config.db_config.user,
    password: config.db_config.password,
    port: config.db_config.port,
    database: config.db_config.database
};
app.use(myConnection(mysql, dbOptions, 'single'));

and then I include my routes, passing the routes the app and log middleware so I can use them in the route:

app.js cont.

var userRoute = require('./routes/users.js')(app,log);
app.use('/users', userRoute);

That actually was a little confusing, but now I get it, I have to pass them into module in order for the module to get the data.

Then in my route file I want to use an object so that I can use the same functionality in other routes, but in the user file in order to use the same connection pool that everything else is using, or at least to not have to set up the connection again I have to pass it the response and request? There's gotta be a better way to do that. It's really ugly that way. Here's the relevant part of

routes/users.js

var User = require('../controllers/User.js');

module.exports = (function(app,log) {
var userR = express.Router();

userR.post('/register', function(req,res){
        var email = req.body.email;
        var password = req.body.password;
        var firstName = req.body.first_name;
        var lastName = req.body.last_name;
        var userId;

        try {
            var query;
            var status = 200;
            var response = '';

            var newUser = {
                email: email,
                password:password,
                first_name: firstName,
                last_name: lastName,
                password: password
            };

            var user = new User(req,res);

            user.register(newUser);
...

};

controllers/User.js

module.exports = function User(req,res) {
this.id = 0;
    this.register = function(newUser){

        var _this = this;
        var deferred = q.defer();
req.getConnection(function(err,connection){
...

There must be a pattern I'm missing here. I should just be able to pass the app or something and have access to the req.getConnection etc.

Thanks.

解决方案

There's kind of a lot going on here, but I'll take a crack at this one.

My first recommendation would be to try to keep your routers pretty slim. It's not labeled, but I'm assuming the largest snippet of code you've provided is your router. There are lots of opinions of course, but if I were doing this here's what my router would look like. I'm assuming you're using Express 4x.

routes/users.js

var User = require('../controllers/user.js');
var userRouter = express.Router();
userRouter.post("/register", User.register);
module.exports = userRouter;

So what we've done here is eliminated the dependency on your app/log middleware.

This means your main file (what I usually call app.js), will look like this:

app.js

var userRouter = require('./routes/users.js');
app.use('/users', userRouter);

This is also where you can put any middleware you chose (logging, body-parsing, error-handling, etc).

In the later versions of Express the above code actually mounts our userRouter to "/users". In this case you will now have a "/users/register" route.

So now since we've pulled out some of the logic of the router, we have to put that somewhere. Typically a router will talk to a controller so let's take a look:

controllers/user.js

var User = require("../models/user.js")
var register = function(req, res, next){
    var email = req.body.email;
    var password = req.body.password;
    var firstName = req.body.first_name;
    var lastName = req.body.last_name;
    var userId;
    var params = {
            email: email,
            password:password,
            first_name: firstName,
            last_name: lastName,
            password: password
        };
    var newUser = new User(params);

    try {
       newUser.register();
        // do other things...
    }
};
module.exports = {register: register};

The first thing you'll notice is that I would have a UserModel file. By doing this, we've de-coupled our model object from this route. Let's say for instance we have a new register route (maybe one of them has an email + pw, the other registers through FB and we have to store different things). We should be able to use the same function (user.register in this case) specified in our model without having to change a whole bunch of things!

Now, here's what a UserModel might look like:

/models/user.js

var connection = require("../lib/connection.js");
var User = function(params){
   this.email = params.email;
   // ...etc
};

User.prototype.register = function(newUser){
    connection.getConnection(function(error, connection){
        //connection.doWhatever();
    });
};

module.exports = User;

Now we've finally gotten to the core of your question. At the top, you'll see we have a connection file. This is where we're going to put all of our DB-related logic like our connection pools.

/lib/connection.js

/*
This will be in some JSON config we'll say
var dbOptions = {
    host: config.db_config.host,
    user: config.db_config.user,
    password: config.db_config.password,
    port: config.db_config.port,
    database: config.db_config.database
};

*/
//This will depend on which version/module/db you're using, but here's what mine looks like
var MySQL = require("mysql");
var config = require("../config/db.json");
connectionPool = MySQL.createPool({host: config.db_config.host, ...});

var getConnection = function(done){
   connectionPool.getConnection(done);
};

module.exports = {getConnection: getConnection};

So, in conclusion, instead of passing your connection along with your request object, we now simply include our short connection module in whichever model file we're in, kindly ask for a connection, and do whatever processing we need to. Also note you'll have to release the connections back into the pool, but I'll leave that as an exercise for you :).

Also, I usually write CoffeeScript, so please excuse any small errors. Let me know if you have need for further clarification.

Cheers, Brennan

这篇关于在快速REST API中使用OOP的最佳方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆