mirror of https://github.com/pelias/api.git
Peter Johnson
10 years ago
14 changed files with 158 additions and 72 deletions
@ -1,13 +1,16 @@ |
|||||||
|
|
||||||
var pkg = require('../package'); |
var pkg = require('../package'); |
||||||
|
|
||||||
function controller( req, res ){ |
function controller( req, res, next ){ |
||||||
|
|
||||||
|
// stats
|
||||||
res.json({ |
res.json({ |
||||||
name: pkg.name, |
name: pkg.name, |
||||||
version: { |
version: { |
||||||
number: pkg.version |
number: pkg.version |
||||||
} |
} |
||||||
}); |
}); |
||||||
|
|
||||||
} |
} |
||||||
|
|
||||||
module.exports = controller; |
module.exports = controller; |
@ -1,32 +1,35 @@ |
|||||||
|
|
||||||
var logger = require('../src/logger'), |
var query = require('../query/suggest'), |
||||||
responder = require('../src/responder'), |
|
||||||
query = require('../query/suggest'), |
|
||||||
backend = require('../src/backend'); |
backend = require('../src/backend'); |
||||||
|
|
||||||
module.exports = function( req, res, next ){ |
function controller( req, res, next ){ |
||||||
|
|
||||||
var reply = { |
|
||||||
date: new Date().getTime(), |
|
||||||
body: [] |
|
||||||
}; |
|
||||||
|
|
||||||
|
// backend command
|
||||||
var cmd = { |
var cmd = { |
||||||
index: 'pelias', |
index: 'pelias', |
||||||
body: query( req.clean ) // generate query from clean params
|
body: query( req.clean ) |
||||||
}; |
}; |
||||||
|
|
||||||
// Proxy request to ES backend & map response to a valid FeatureCollection
|
// query backend
|
||||||
backend().client.suggest( cmd, function( err, data ){ |
backend().client.suggest( cmd, function( err, data ){ |
||||||
|
|
||||||
if( err ){ return responder.error( req, res, next, err ); } |
var docs = []; |
||||||
if( data && data.pelias && data.pelias.length ){ |
|
||||||
|
|
||||||
// map options to reply body
|
// handle backend errors
|
||||||
reply.body = data['pelias'][0].options; |
if( err ){ return next( err ); } |
||||||
|
|
||||||
|
// map response to a valid FeatureCollection
|
||||||
|
if( data && Array.isArray( data.pelias ) && data.pelias.length ){ |
||||||
|
docs = data['pelias'][0].options || []; |
||||||
} |
} |
||||||
|
|
||||||
return responder.cors( req, res, reply ); |
// respond
|
||||||
|
return res.status(200).json({ |
||||||
|
date: new Date().getTime(), |
||||||
|
body: docs |
||||||
|
}); |
||||||
}); |
}); |
||||||
|
|
||||||
}; |
} |
||||||
|
|
||||||
|
module.exports = controller; |
@ -1,14 +0,0 @@ |
|||||||
|
|
||||||
var express = require('express'), |
|
||||||
app = express(); |
|
||||||
|
|
||||||
// middleware modules
|
|
||||||
// app.use( require('cookie-parser')() );
|
|
||||||
|
|
||||||
// enable client-side caching of 60s by default
|
|
||||||
app.use(function(req, res, next){ |
|
||||||
res.header('Cache-Control','public,max-age=60'); |
|
||||||
next(); |
|
||||||
}); |
|
||||||
|
|
||||||
module.exports = app; |
|
@ -0,0 +1,8 @@ |
|||||||
|
|
||||||
|
// handle not found errors
|
||||||
|
function middleware(req, res) { |
||||||
|
res.header('Cache-Control','public,max-age=300'); // 5 minute cache
|
||||||
|
res.status(404).json({ error: 'not found: invalid path' }); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = middleware; |
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
// handle application errors
|
||||||
|
function middleware(err, req, res, next) { |
||||||
|
res.header('Cache-Control','no-cache'); |
||||||
|
if( res.statusCode < 400 ){ res.status(500); } |
||||||
|
res.json({ error: err }); |
||||||
|
} |
||||||
|
|
||||||
|
module.exports = middleware; |
@ -1,33 +0,0 @@ |
|||||||
|
|
||||||
// send a reply that is capable of JSON, CORS and JSONP
|
|
||||||
function cors( req, res, obj ){ |
|
||||||
res.header('Charset','utf8'); |
|
||||||
res.header('Cache-Control','public,max-age=60'); |
|
||||||
res.header('Access-Control-Allow-Origin', '*'); |
|
||||||
res.header('Access-Control-Allow-Methods', 'GET'); |
|
||||||
res.header('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); |
|
||||||
res.header('Access-Control-Allow-Credentials', true); |
|
||||||
res.header('X-Powered-By', 'pelias'); |
|
||||||
|
|
||||||
// jsonp
|
|
||||||
if( req.query && req.query.callback ){ |
|
||||||
res.header('Content-type','application/javascript'); |
|
||||||
return res.send( req.query.callback + '('+ JSON.stringify( obj ) + ');' ); |
|
||||||
} |
|
||||||
|
|
||||||
// regular json
|
|
||||||
res.header('Content-type','application/json'); |
|
||||||
return res.json( obj ); |
|
||||||
} |
|
||||||
|
|
||||||
// send an error
|
|
||||||
function error( req, res, next, err ){ |
|
||||||
console.error( 'application error:', err ); |
|
||||||
// mask error from user (contains paths)
|
|
||||||
return cors( req, res, { error: 'application error' } ); |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = { |
|
||||||
cors: cors, |
|
||||||
error: error |
|
||||||
}; |
|
@ -0,0 +1,17 @@ |
|||||||
|
|
||||||
|
#> invalid path |
||||||
|
path: '/notexist' |
||||||
|
|
||||||
|
#? not found |
||||||
|
response.statusCode.should.equal 404 |
||||||
|
|
||||||
|
#? content-type header correctly set |
||||||
|
response.should.have.header 'Content-Type','application/json; charset=utf-8' |
||||||
|
|
||||||
|
#? cache-control header correctly set |
||||||
|
response.should.have.header 'Cache-Control','public,max-age=300' |
||||||
|
|
||||||
|
#? should respond in json with server info |
||||||
|
should.exist json |
||||||
|
should.exist json.error |
||||||
|
json.error.should.equal 'not found: invalid path' |
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
#> cross-origin resource sharing |
||||||
|
path: '/' |
||||||
|
|
||||||
|
#? access control headers correctly set |
||||||
|
response.should.have.header 'Access-Control-Allow-Origin','*' |
||||||
|
response.should.have.header 'Access-Control-Allow-Methods','GET' |
||||||
|
response.should.have.header 'Access-Control-Allow-Headers','X-Requested-With,content-type' |
||||||
|
response.should.have.header 'Access-Control-Allow-Credentials','true' |
@ -0,0 +1,10 @@ |
|||||||
|
|
||||||
|
#> jsonp |
||||||
|
path: '/?callback=test' |
||||||
|
|
||||||
|
#? content-type header correctly set |
||||||
|
response.should.have.header 'Content-Type','application/javascript; charset=utf-8' |
||||||
|
|
||||||
|
#? should respond with jsonp |
||||||
|
should.exist response.body |
||||||
|
response.body.substr(0,5).should.equal 'test('; |
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
#> valid suggest query |
||||||
|
path: '/suggest?input=a&lat=0&lon=0' |
||||||
|
|
||||||
|
#? 200 ok |
||||||
|
response.statusCode.should.equal 200 |
||||||
|
|
||||||
|
#? valid response |
||||||
|
now = new Date().getTime() |
||||||
|
should.exist json |
||||||
|
should.not.exist json.error |
||||||
|
should.exist json.date |
||||||
|
json.date.should.be.within now-1000, now+1000 |
||||||
|
should.exist json.body |
||||||
|
json.body.should.be.instanceof Array |
Loading…
Reference in new issue