diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index d2119dd2694ab2aa24186a180f3b8bb67b82518f..5bf07c0b2f04d4d4c3617d89ece44cf2400c47b3 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -26,6 +26,8 @@ const simulation = require('./simulation');
 
 const user = require('./user');
 
+const classroom = require('./classroom');
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
@@ -40,5 +42,6 @@ api.use('/region', cache('15 day'), region);
 api.use('/city', cache('15 day'), city);
 api.use('/school', cache('15 day'), school);
 api.use('/spatial', cache('1 day'), spatial);
+api.use('/classroom', cache('15 day'), classroom);
 
 module.exports = api;
diff --git a/src/libs/routes/classroom.js b/src/libs/routes/classroom.js
new file mode 100644
index 0000000000000000000000000000000000000000..37186e56f098ee294ca7267e5970eff5d81e318c
--- /dev/null
+++ b/src/libs/routes/classroom.js
@@ -0,0 +1,147 @@
+const express = require('express');
+
+const classroomApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`);
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+let rqf = new ReqQueryFields();
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'school',
+    table: 'escola',
+    tableField: 'id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    }
+}).addValue({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'municipio_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'estado_id',
+        table: 'escola'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: 'nome',
+    resultField: 'region_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'ano_censo',
+        table: 'escola'
+    }
+}).addValue({
+    name: 'adm_dependency',
+    table: 'dependencia_adm',
+    tableField: 'nome',
+    resultField: 'adm_dependency_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'dependencia_adm_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: 'dependencia_adm',
+    tableField: 'nome',
+    resultField: 'adm_dependency_detailed_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'dependencia_adm_priv',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'locality',
+    table: 'escola',
+    tableField: 'cod_localizacao',
+    resultField: 'locality',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'cod_localizacao',
+        table: 'escola'
+    }
+});
+
+classroomApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+    console.log(req.filter);
+    req.sql.from('escola')
+        .field('SUM(escola.num_salas)', 'total')
+        .field("'Brasil'", 'name')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('escola.situacao_de_funcionamento = 1 AND escola.local_func_predio_escolar = 1');
+    next();
+}, query, response('classroom'));
+
+module.exports = classroomApp;
diff --git a/src/test/classroom.js b/src/test/classroom.js
new file mode 100644
index 0000000000000000000000000000000000000000..54d058aee1e5f213c6c8ba92d28dcdf812462354
--- /dev/null
+++ b/src/test/classroom.js
@@ -0,0 +1,223 @@
+process.env.NODE_ENV = 'test';
+
+const chai = require('chai');
+
+const dirtyChai = require('dirty-chai');
+
+chai.use(dirtyChai);
+
+const chaiXml = require('chai-xml');
+
+chai.use(chaiXml);
+
+const chaiHttp = require('chai-http');
+
+const assert = chai.assert;
+
+const expect = chai.expect;
+
+const should = chai.should(); // actually call the function
+
+const libs = `${process.cwd()}/libs`;
+
+const server = require(`${libs}/app`);
+
+chai.use(chaiHttp);
+describe('request classrooms', () => {
+
+    it('should list classrooms', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=city:4106902')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=state:41')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=region:4')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=adm_dependency:3')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=adm_dependency_detailed:5')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid filters', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?filter=locality:1')
+            .end((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();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=city')
+            .end((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('city_name');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=state')
+            .end((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('state_name');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=region')
+            .end((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('region_name');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=adm_dependency')
+            .end((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('adm_dependency_name');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=adm_dependency_detailed')
+            .end((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('adm_dependency_detailed_name');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with valid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/classroom?dims=locality')
+            .end((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('locality');
+                res.body.result[0].should.have.property('total');
+                done();
+            });
+    });
+
+    it('should list classrooms with invalid dimensions', (done) => {
+        chai.request(server)
+            .get('/api/v1/class?dims=foo,bar')
+            .end((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();
+            });
+    });
+});