Expo

Found a very cool project: https://expo.io

I already started working on react native client for Mongo Explorer, but decided to check Expo first. I had another project I wanted to build – food ordering api, so I decided to build it with Expo. Here is the source: https://github.com/alishdev/food-ordering-app

The Expo experience is extremely positive. Very quickly I was able to build a simple mobile app and run it my phone (even without Apple developer license). I see how useful could be to use Expo when you working on UI/UX with the client. Developers can quickly build screens so customers can test them on their phones when developers share the link to the project.

MERN

When I started my MEAN path I thought that I will learn all technologies related. With Mongo-Explorer-API project I used 3 out of 4 technologies:

MongoDB (M)

Express.JS (E)

and Node.JS (N)

I was planning to continue with Angular 2 in the client project which supposed to connect the API. After some consideration I came to conclusion that I want to make a detour and instead of building a Web client project in Angular 2 (A) I will work on mobile client first using React Native (N).

So I am taking a detour with MERN. I am so excited!

co

Found out that examples in MongoDB use co generator to make it easier to write and read async functions:
https://github.com/tj/co

Something very complicated (because of multiple callbacks) like:
var db = new Database('test', new Server(connectionString.server, connectionString.port));
db.open(function(err, db) {
if (err)
cb(err);
var adminDb = db.admin();
adminDb.listDatabases(function(err, dbs) {
if (err)
cb(err);
cb(null, dbFound);
});
});

becomes very simple when using co:

return co(function*() {
try
{
let db = yield MongoClient.connect(url, {ssl:connectionString.ssl});
let dbs = yield db.command({listDatabases:1});
}
catch()
{}
}

Heroku

I decide to post the Mongo Explorer API project to Heroku.

Here is what had to do:

  1. Create an account on Heroku
  2. Installed Heroku Command Line Interface (CLI) with homebrew:
     brew install Heroku
  3. Logger on to Heroku:
     heroku login
  4. Created an app:
    heroku create
  5. Deploy the code:
    git push heroku master
  6. Obviously, the app crashed and did not run, so I had to check the logs:
    heroku logs --tail

It took me couple hours to figure out how to prepare my project to run on Heroku:

  1. I had to add start script in package.json. Heroku uses Procfile, but if file is not found then it looks for start script:
    “scripts”: {
    “start”: “node app.js”
    }
  2. Heroku assigns port dynamically, so I had to change startup code from: app.listen(config.get(‘NODE_PORT’));
    to
    var port = process.env.PORT || config.get('NODE_PORT');
    app.listen(port);
  3. Now the app started, but Swagger UI was failing so I had do the last change: in swaggerDefinition variable I had to change
    host from localhost:4000 to dry-spire-23794.herokuapp.com
  4. The last thing was adding CORS support.

And now my app runs on:

https://dry-spire-23794.herokuapp.com/

 

Swagger

Time to add some UI.

Fortunately, I know pretty easy and cool way to visualize API – my old friend Swagger. I used Swagger in one of my projects in ASP.NET and decided to use it for my Node.JS project. I found pretty good article on adding Swagger support:

http://mherman.org/blog/2016/05/26/swagger-and-nodejs/#.WPJ-y1Pytn5

Just committed first basic Swagger description in my project: https://github.com/alishdev/mongo-explorer-api which will be accessible from http://localhost:4000/api-docs/

Passing connection information

Since the goal of the API to connect to any database and explore it the API project cannot store connection information in config file. Instead connection info must be passed with every request.

Initially I was thinking to pass info in the body of the request, but since I have to implement GET requests also (which according to REST is not supposed to have bodies) I had two options:

  1. put connection info into request parameters (not safe)
  2. put connection info into request header

The latter solution seems to be the correct and simplest one: I used middleware in Express.js to read header and populate request’s connectionString parameter.

API Design

I found couple helpful links for anyone who wants to build API project:

http://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/

https://scotch.io/tutorials/keeping-api-routing-clean-using-express-routers

So at this point the API structure I think will be following:

db – get list of all databases
db/:dbname – get, put, post, delete db named as :dbname

db/:dbname/collection – get list of all collections in db named as :dbname
db/:dbname/collection/:colname – get, put, post, delete collection named :colname in db named as :dbname

db/:dbname/collection:colname/doc – get list of all documents in collection named :colname in db named as :dbname
db/:dbname/collection/:colname/doc/:docid – get, put, post, delete document with id :docid in  collection named :colname in db named as :dbname

Mongo Explorer API

There was some break since I have written anything, but I was not abandoning the project. Instead I took a class provided by MongoDB University:

https://university.mongodb.com/courses/M101N/about

I also read a book on Node.js:

 

When reading this book I felt at home first time I started learning web development – probably because I am really a back end developer.

After some consideration I came to conclusion that I need to start with API project first, so I added a new project on Github:

https://github.com/alishdev/mongo-explorer-api

ng-book

While working on the angular part of the mongo-explorer I came to conclusion that classes I watched are not very helpful. I saw how the application was built, but I still did not understand why the developer chose to use things certain way.

After that I started searching for a book on Angular 2 and found this:

ng-book-2

https://www.ng-book.com/2/

Normally I like printed books, but in case of Angular 2 which is still in development it’s better to have electronic version which is being constantly updated.