diff --git a/package.json b/package.json
index 141451dd86928717b6862a62654e355a8d68157e..4f5a9da110cb8d0ecb31d2e52a763abf6b44e4d4 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
     "test": "mocha"
   },
   "dependencies": {
+    "apicache": "0.0.14",
     "body-parser": "^1.13.1",
     "cookie-parser": "^1.3.5",
     "cors": "^2.7.1",
@@ -21,6 +22,7 @@
     "method-override": "^2.3.3",
     "monetdb-pool": "0.0.8",
     "nconf": "^0.6.x",
+    "squel": "^5.4.2",
     "winston": "^2.2.0"
   },
   "license": "MIT",
diff --git a/server.js b/server.js
new file mode 100644
index 0000000000000000000000000000000000000000..f27cd5c80693c1b31bbd500a5fcbae00a86b957d
--- /dev/null
+++ b/server.js
@@ -0,0 +1,13 @@
+var debug = require('debug')('node-express-base')
+
+var libs = process.cwd() + '/libs/'
+var config = require(libs + 'config')
+var log = require(libs + 'log')(module)
+var app = require(libs + 'app')
+
+app.set('port', process.env.PORT || config.get('port') || 3000)
+
+var server = app.listen(app.get('port'), function() {
+  debug('Express server listening on port ' + server.address().port)
+  log.info('Express server listening on port ' + server.address().port)
+})
diff --git a/src/libs/middlewares/dimensions.js b/src/libs/middlewares/dimensions.js
new file mode 100644
index 0000000000000000000000000000000000000000..c17e4a6d2e00c1e5dc47455f4959cf9f33a0ad09
--- /dev/null
+++ b/src/libs/middlewares/dimensions.js
@@ -0,0 +1,48 @@
+/**
+* Dimensions middleware
+*
+* EXAMPLE:
+* Use it with no parameters to get all the dimensions specified
+* app.get('/', dimensions(), function(req, res, next){})
+*
+* Use it with an array of accepted values
+* app.get('/', dimensions(['year', 'location']), function(req, res, next){})
+*
+* Use it globally
+* app.use(dimensions())
+*/
+
+function intersect(a, b) {
+    var t
+    if (b.length > a.length) t = b, b = a, a = t
+    return a.filter(function (e) {
+        if (b.indexOf(e) !== -1) return true
+    })
+}
+
+function dimensions(dims) {
+    return function(req, res, next) {
+        req.dims = {}
+        if(req.query.dims) {
+            var params = req.query.dims.split(",")
+            var dimObj = {}
+            for(var i=0; i<params.length; ++i) {
+                var kv = params[i].split(":")
+                dimObj[kv[0]] = (typeof kv[1] === 'undefined') ? null : kv[1]
+            }
+            // If the dims array exists and is not empty
+            if(typeof dims !== 'undefined' && dims.length > 0) {
+                var intersection = intersect(dims, Object.keys(dimObj))
+                for(var i=0; i<intersection.length; ++i) {
+                    req.dims[intersection[i]] = dimObj[intersection[i]]
+                }
+            } else {
+                req.dims = dimObj
+            }
+        }
+        console.log(req.dims)
+        next()
+    }
+}
+
+module.exports = dimensions
diff --git a/src/libs/middlewares/query.js b/src/libs/middlewares/query.js
new file mode 100644
index 0000000000000000000000000000000000000000..80f00348bf4fc93c3d85506f298e14545679186c
--- /dev/null
+++ b/src/libs/middlewares/query.js
@@ -0,0 +1,17 @@
+var libs = process.cwd() + '/libs/'
+var conn = require(libs + 'db/monet')
+var log = require(libs + 'log')(module)
+var queryExec = require(libs + 'db/query_exec')
+
+function query(req, res, next) {
+    log.debug(req.query)
+    queryExec(req.query.text, req.query.values)
+    .then(function(result) {
+        log.debug(result)
+        console.log("PEOPO");
+        req.result = result
+        next()
+    })
+}
+
+module.exports = query
diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index 29fe4564de83f21a943b21bb6fbd57e02310b709..64c84519bda37a6d4d67819d48ce958dc0c8254c 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -4,6 +4,7 @@ const enrollment = require('./enrollment');
 const state = require('./state');
 const region = require('./region');
 const city = require('./city');
+const test = require('./cities');
 
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
@@ -14,5 +15,6 @@ api.use('/v1/enrollment', enrollment);
 api.use('/v1/state',      state);
 api.use('/v1/region',     region);
 api.use('/v1/city',       city);
+api.use('/v1/test', test);
 
 module.exports = api;
diff --git a/src/libs/routes/cities.js b/src/libs/routes/cities.js
new file mode 100644
index 0000000000000000000000000000000000000000..fd0302635c7ab4ded59bfb1bc41efe5150a5d929
--- /dev/null
+++ b/src/libs/routes/cities.js
@@ -0,0 +1,42 @@
+var express = require('express')
+var xml = require('js2xmlparser')
+var router = express.Router()
+var squel = require('squel')
+
+var libs = process.cwd() + '/libs/'
+
+var log = require(libs + 'log')(module)
+var config = require(libs + 'config')
+
+var conn = require(libs + 'db/monet')
+var query = require(libs + 'middlewares/query')
+
+function response(req, res) {
+    if (req.query.format === 'csv') {
+        res.csv(req.result.data)
+    } else if (req.query.format === 'xml') {
+        res.send(xml("result", JSON.stringify({city: req.result.data})))
+    }
+    else {
+        res.json({
+            result: req.result.data
+        })
+    }
+}
+
+router.get('/', function(req, res, next) {
+    req.query = squel.select().from('municipios').limit(2).toParam()
+    next()
+}, query, response)
+
+router.get('/:id', function(req, res, next) {
+    req.query = squel.select().from('municipios').where('pk_municipio_id=?', parseInt(req.params.id, 10)).toParam()
+    next()
+}, query, response)
+
+router.get('/state/:id', function(req, res, next) {
+    req.query = squel.select().from('municipios').where('fk_estado_id=?', parseInt(req.params.id, 10)).toParam()
+    next()
+}, query, response)
+
+module.exports = router
diff --git a/src/libs/routes/city.js b/src/libs/routes/city.js
index c7deb75f1f7a506715f5dacd4d11f0eff4c0ef85..1b390498d9c1fce94c6d71af7d17d7854ba5fdd8 100644
--- a/src/libs/routes/city.js
+++ b/src/libs/routes/city.js
@@ -21,7 +21,7 @@ function response(req, res) {
 }
 
 cityApp.get('/', (req, res) => {
-    const citySql = 'SELECT * FROM municipios';
+    const citySql = 'SELECT * FROM municipios LIMIT 5';
     dbQuery(yearSql).then((result) => {
         req.result = result;
         return response(req, res);
diff --git a/src/libs/routes/regions.js b/src/libs/routes/regions.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfbbcd946572a8a30ebf00536ce9cbf544226f7f
--- /dev/null
+++ b/src/libs/routes/regions.js
@@ -0,0 +1,38 @@
+var express = require('express')
+var xml = require('js2xmlparser')
+var router = express.Router()
+var squel = require('squel')
+
+var libs = process.cwd() + '/libs/'
+
+var log = require(libs + 'log')(module)
+var config = require(libs + 'config')
+
+var conn = require(libs + 'db/monet')
+
+var query = require(libs + 'middlewares/query')
+
+function response(req, res) {
+    if (req.query.format === 'csv') {
+        res.csv(req.result.data)
+    } else if (req.query.format === 'xml') {
+        res.send(xml("result", JSON.stringify({state: req.result.data})))
+    }
+    else {
+        res.json({
+            result: req.result.data
+        })
+    }
+}
+
+router.get('/', function(req, res, next) {
+    req.query = squel.select().from('regioes').toParam()
+    next()
+}, query, response)
+
+router.get('/:id', function(req, res, next) {
+    req.query = squel.select().from('regioes').where('pk_regiao_id=?', parseInt(req.params.id, 10)).toParam()
+    next()
+}, query, response)
+
+module.exports = router
diff --git a/src/libs/routes/states.js b/src/libs/routes/states.js
new file mode 100644
index 0000000000000000000000000000000000000000..79959ef8fd4a19c3afc3f51328ec737396cb0bbe
--- /dev/null
+++ b/src/libs/routes/states.js
@@ -0,0 +1,44 @@
+var express = require('express')
+var xml = require('js2xmlparser')
+var router = express.Router()
+var squel = require('squel')
+
+var libs = process.cwd() + '/libs/'
+
+var log = require(libs + 'log')(module)
+var config = require(libs + 'config')
+
+var conn = require(libs + 'db/monet')
+
+var query = require(libs + 'middlewares/query')
+
+function response(req, res) {
+    console.log('respostas :)')
+    if (req.query.format === 'csv') {
+        res.csv(req.result.data)
+    } else if (req.query.format === 'xml') {
+        res.send(xml("result", JSON.stringify({state: req.result.data})))
+    }
+    else {
+        res.json({
+            result: req.result.data
+        })
+    }
+}
+
+router.get('/', function(req, res, next) {
+    req.query = squel.select().from('estados').toParam()
+    next()
+}, query, response)
+
+router.get('/:id', function(req, res, next) {
+    req.query = squel.select().from('estados').where('pk_estado_id = ?', parseInt(req.params.id, 10)).toParam()
+    next()
+}, query, response)
+
+router.get('/region/:id', function(req, res, next) {
+    req.query = squel.select().from('estados').where('fk_regiao_id = ?', parseInt(req.params.id, 10)).toParam()
+    next()
+}, query, response)
+
+module.exports = router
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6b67ff84daf91c4abcb98e014cd8beee5c5c42f
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,142 @@
+var chai = require('chai');
+var chaiHttp = require('chai-http');
+var assert = chai.assert;
+var expect = chai.expect;
+var should = chai.should(); //actually call the function
+var server = require('../libs/app');
+
+chai.use(chaiHttp);
+
+describe('request enrollments', function(){
+
+  it('should list enrollments', function(done){
+    chai.request(server)
+      .get('/api/v1/enrollments')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('name');
+        res.body.result[0].should.have.property('total');
+        done();
+      })
+  });
+});
+
+describe('request regions', function(){
+
+  it('should list all regions', function(done){
+    chai.request(server)
+      .get('/api/v1/regions')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('pk_regiao_id');
+        res.body.result[0].should.have.property('nome');
+        done();
+      })
+  });
+
+  it('should list region by id', function(done){
+    chai.request(server)
+      .get('/api/v1/regions/1')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result.should.have.length(1);
+        res.body.result[0].should.have.property('pk_regiao_id');
+        res.body.result[0].should.have.property('nome');
+        done();
+      })
+  });
+});
+
+describe('request states', function(){
+
+  it('should list all states', function(done){
+    chai.request(server)
+      .get('/api/v1/states')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('pk_estado_id');
+        res.body.result[0].should.have.property('fk_regiao_id');
+        res.body.result[0].should.have.property('nome');
+        done();
+      })
+  });
+
+  it('should list a state by id', function(done){
+    chai.request(server)
+      .get('/api/v1/states/11')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result.should.have.length(1);
+        res.body.result[0].should.have.property('pk_estado_id');
+        res.body.result[0].should.have.property('fk_regiao_id');
+        res.body.result[0].should.have.property('nome');
+        done();
+      })
+  });
+
+  it('should list states by region id', function(done){
+    chai.request(server)
+      .get('/api/v1/states/region/1')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('pk_estado_id');
+        res.body.result[0].should.have.property('fk_regiao_id');
+        res.body.result[0].should.have.property('nome');
+        done();
+      })
+  });
+});
+
+describe('request cities', function(){
+
+  it('should list all cities', function(done){
+    chai.request(server)
+      .get('/api/v1/cities')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('pk_municipio_id');
+        res.body.result[0].should.have.property('fk_estado_id');
+        res.body.result[0].should.have.property('nome');
+        res.body.result[0].should.have.property('codigo_ibge');
+        done();
+      })
+  });
+
+  it('should list a city by id', function(done){
+    chai.request(server)
+      .get('/api/v1/cities/1')
+      .end(function(err, res){
+        res.should.have.status(200);
+        res.should.be.json;
+        res.body.should.have.property('result');
+        res.body.result.should.be.a('array');
+        res.body.result[0].should.have.property('pk_municipio_id');
+        res.body.result[0].should.have.property('fk_estado_id');
+        res.body.result[0].should.have.property('nome');
+        res.body.result[0].should.have.property('codigo_ibge');
+        done();
+      })
+  });
+
+});