Pregunta

I'm trying to create a Node (and Express) based app which is functionally similar to a WebAPI app using Mongo as the data store. I'm trying to use TypeScript (and also VS 2013).

I've gotten it to work, and now I'm trying to clean it up.

First, Express 4.1.1 is available, but no typings for it are.

Second, What's the proper way to access Mongo - both making a connection, and querying a collection - such that it's async the way Node would like it to be (so I'm not blocking, etc)? Should I be using q/Promises?

Third, What's the proper way (in this setup) to be accessing a method in another file? I've wrestled for awhile with import/export/require/module/class to get what I think seems ok, but what a pain to get there. Here's what I have:

app.ts with some imports, etc and a reference

/// <reference path='./scripts/typings/node/node.d.ts' />

import express = require('express');
import http = require('http');
import path = require('path');

import badgeApi = require('./routes/api/Badge');

var app = express();
...
new badgeApi.Badge();
app.get('/badge', badgeApi.Badge.ListAll);
...

And then, some generic DB code:

/// <reference path='../../scripts/typings/mongodb/mongodb.d.ts' />

import util = require('util');
import mongodb = require('mongodb');

export var ConnectDataStore: (dbname: string, dbuser: string, dbpass: string) => mongodb.Db;

ConnectDataStore = (dbname: string, dbuser: string = 'xxxx', dbpass: string = 'xxxx') => {
    var baseMongoConnect: string = 'xxxx';
    var mongoConnect = util.format(baseMongoConnect, dbuser, dbpass, dbname);
    var DB: mongodb.Db;

    mongodb.MongoClient.connect(mongoConnect, (err, db) => {
        if (!err) {
            DB = db;
            return DB;
        }
        else {
            throw err;
        }
    });
}

And then Badge.ts

import util = require('util');
import express = require('express');
import mongodb = require('mongodb');
import datastore = require('./DataStore');

export class Badge {
    private static DB: mongodb.Db = null;

    constructor() {
        Badge.DB = datastore.ConnectDataStore('credential', 'xxxx', 'xxxx')
    }

    public static ListAll(req: express.Request, res: express.Response): void {
        Badge.DB.collection('badge', (collErr, coll) => {
            coll.find().toArray((arrayErr, badges) => {
                if (badges.length > 0) {
                    res.jsonp(200, badges);
                }
                else {
                    res.send(200, 'No Badges');
                }
            });
        });
    }
}

Now I know this doesn't exactly work - ConnectDataStore is wrong (it doesn't return a Db as it's supposed to). I was starting to workaround that by having it return a promise when I noticed I was using express 3.5.2, not 4.1.1 and it all finally got to me - this stuff is not very solid.

Of course, I'm probably missing something, but I don't know what!

Any direction around this soup would be appreciated!

¿Fue útil?

Solución

Until there's definition file for Express 4+, I'd suggest you use JavaScript for the core of the application (as it shouldn't need to change much) and use TypeScript for things like application logic (controllers, etc.). In a Node.JS, it's easy to mix and match.

I'd use a promise to handle the MongoDB connection or make the connection early enough that the application hasn't actually started serving web pages until the MongoDB connection has been successfully established.

The 3.0 typings for Express may work with the 4+ version in many places, as the signatures are often the same.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top