Tajusin juuri, että pieni homma, jota olen huvikseni väsäillyt, on jakamisen arvoinen. Se on REST-rajapinta LDAP-hakemistoon, toteutettu Bottlella. Tässä vaiheessa se on aika pintasilaus, sillä pystyy lukemaan hakemistosta käyttäjäolioita JSON-mappingilla. Mutta samanlaisia kyselyitä on hyvin helppoa lisätä.
from bottle import Bottle, request, auth_basic, HTTPError import ldap, json server = 'ldap://ldap.example.fi/' userbase = 'ou=Users,o=Example,c=FI' def qualify_user(user): return 'cn=%s,ou=Staff,%s' % (user, userbase) def setup_prov_service(): prov = Bottle() ldapcon = ldap.initialize(server) #ldapcon.start_tls_s() def ldapbind(user, password): try: ldapcon.simple_bind_s(qualify_user(user), password) except ldap.INVALID_CREDENTIALS: return False return True @prov.route('/') def root(): return "I'm working with bottle" def make_search(base, filter, scope=ldap.SCOPE_SUBTREE): result = ldapcon.search_s(base, scope, filter) if not result: return HTTPError(404, 'No such LDAP object') results = [] for dn, attrs in result: attrs['dn'] = [dn] results.append(attrs) return dict(filter=filter, numresults=len(results), results=results) @prov.route('/user/<cn>') @auth_basic(ldapbind, realm='LDAP directory on '+server) def get_user(cn): return make_search(userbase, '(cn=%s)' % cn) return prov if __name__ == '__main__': setup_prov_service().run(port=8888)
REST-rajapintojen suunnittelu on mielenkiintoista, sillä HTTP tarjoaa paljon "hyviä käytäntöjä" erilaisten pyyntöjen tekemiseen. Joskus ne soveltuvat paremmin, joskus huonommin siihen, mitä toiminnallisuutta yritetään tarjota. Ne eivät ole kovia vaatimuksia syntaksista tai muusta, vaan pehmeitä toiveita konseptuaalisesta eheydestä ja yllätyksettömyydestä. http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Tämän sivuseurauksena törmäsin hyvin mielenkiintoiseen keskusteluun siitä, mitä HTTP-vastauksen "300 multiple choices" sisällön pitäisi olla: https://github.com/Respect/Rest/issues/39