We hebben op dit ogenblik 5 openstaande vacatures. Meer bepaald:
Zin om bij een bende degelijk-werk-afleverende nutcases terecht te komen? Down-to-earth als geen ander? Dan moet je bij ons zijn.
We zijn een jong bedrijf waar we één voor één gepassioneerd zijn door het internet. Er heerst een losse sfeer, maar zonder de deadlines of de kwaliteit uit het oog te verliezen. Bij ons sta je er ook nooit alleen voor, want kennis delen is één van onze kernwaarden. We willen namelijk dat we allemaal continu beter worden in onze job.
Onze kantoren, in Gent, zijn uiterst rustig gelegen, vlak bij het centrum (neem dat maar letterlijk) en uitermate vlot bereikbaar, zowel met de auto, met de fiets als met het openbaar vervoer. Geen sprake van file-stress dus.
Voor vacature.com werkte Marlon de voorbije maanden de nieuwe Mijn/Vacature af. Mijn/Vacature laat je toe
- online een CV aan te maken (manueel, door het importeren van een Microsoft Word document of door je gegevens uit LinkedIn op te halen) en zo gevonden te worden door werkgevers
- vacatures te ontvangen op maat van je profiel
- online te solliciteren
Jobs & Careers zorgde zelf voor analyse en design. Marlon zorgde voor de volledige ontwikkeling op maat van dit onderdeel van de website. Op basis van de analyse van Jobs & Careers bouwden we deze applicatie terug van nul op. De vorige versie van Mijn/Vacature werd volledig vervangen met de bedoeling verdere productontwikkeling mogelijk te maken.
Specifiek voor deze applicatie zijn o.a. integratie tussen PHP en Microsoft SQL Server, het gebruik van de LinkedIn API, integratie met verschillende SOAP webservices (voor gepersonaliseerde zoekopdrachten, Word document parsing, CV updates, online solliciteren, …) en integratie met het CRM systeem van Vacature.
Ook de migratie van alle gegevens uit de vorige versie van Mijn/Vacature (profielen, cv’s, gepersonaliseerde zoekopdrachten, diploma’s, werkervaringen, …) naar de nieuwe versie werd door Marlon afgewerkt.
Ondertussen is al een nieuwe versie van deze Mijn/Vacature gelanceerd. Mijn/Vacature is een onderdeel van de vacature.com site dat constant evolueert.
CouchDB is *hot*, getuige de verschillende blogposts en tutorials die momenteel overal opduiken. Niet op de kar springen betekent later gegarandeerd een drive-by door collega developers met de gekende vinger door de achteruitkijkspiegel dus wie zijn wij om langs de kant van de weg te blijven staan.
CouchDB is een database die momenteel volop wordt ontwikkeld door de Apache Foundation. Het huidige releasenummer (0.9.0) laat blijken dat het project nog steeds work in progress is. Dat neemt echter niet weg dat wij het project als ontwikkelaars met een open geest al eens niet van dichtbij kunnen bekijken.
Wat CouchDB precies is en wat je er allemaal mee kan doen lees je best op de CouchDB-website zelf. Je vind er algemene documentatie over de werking van CouchDB, een installatiegids maar ook implementatie-voorbeelden voor verschillende programmeertalen (PHP, .Net, Ruby, …). Eén van de grote voordelen van CouchDB is dat de database aangesproken kan worden via een REST-API. Inderdaad: GET, POST, PUT en DELETE. Deze blogpost gaat wat dieper in op een concrete implementatie in PHP voor communcatie met zo’n CouchDB-database door gebruik van de Zend Framework component Zend_Rest_Client.
Zend_Rest_Client vind je momenteel al terug in de laatste versie van het framework en kan je hier downloaden. Er wordt op dit moment hard gewerkt aan een “Zend_CouchDB”-component, maar deze ontwikkeling zit nog steeds in de incubator. Nog even afwachten dus.
Eens je CouchDB-daemon draait is het opzetten van de communicatie via Zend_Rest_Client erg makkelijk (default poort van de CouchDB service is 5984):
$client = new Zend_Rest_Client('http://localhost:5984');
In CouchDB is geen sprake van records of rows. Een eenheid van data wordt er een document genoemd. Zo’n document bevat dan enkele door jouw gespecifieerde velden. Een document kan als JSON doorgestuurd worden naar de server. (standaard wordt steeds JSON gebruikt, dit kan eventueel worden gewijzigd)
Een document toevoegen doe je door een POST-request te versturen naar de server. (Meer informatie omtrent het gebruik van de soorten requests vind je hier)
Gebruik makende van de Zend Framework componenten Zend_Rest_Client, Zend_Json en Zend_Debug bekomen we volgende resultaat:
// compose document
$document = array();
$document['title'] = 'document title';
$document['content'] = 'document content';
// JSON-ize document
$document = Zend_Json::encode($document);
// add document (use POST here)
$response = $client->restPost('test', $document);
// print response
Zend_Debug::dump($response);
Indien alles goed ging krijg je als response een “201 – Created”-boodschap terug:
object(Zend_Http_Response)#6 (5) {
["version:protected"] => string(3) "1.1"
["code:protected"] => int(201)
["message:protected"] => string(7) "Created"
["headers:protected"] => array(6) {
["Server"] => string(39) "CouchDB/0.10.0a773105 (Erlang OTP/R12B)"
["Location"] => string(59) "http://localhost:5984/test/c447a8366d74d880f35720d92d68419e"
["Date"] => string(29) "Tue, 19 May 2009 18:23:59 GMT"
["Content-type"] => string(24) "text/plain;charset=utf-8"
["Content-length"] => string(2) "73"
["Cache-control"] => string(15) "must-revalidate"
}
["body:protected"] => string(73) "{"ok":true,"id":"c447a8366d74d880f35720d92d68419e","rev":"1-3753022840"}
"
}
In de body van deze response krijg je het uniek genereerde ID van het document terug alsook het revisie-nummer (hier 1). Indien gewenst kan je wanneer je een document toevoegt zelf ook een uniek ID kiezen. (vb.: doc1, doc2, doc3, …)
Een document ophalen gebeurt met een GET-request op basis van het unieke ID:
// get document
$response = $client->restGet('test/c447a8366d74d880f35720d92d68419e');
// un-Json-ize document
$document = Zend_Json::decode($response->getBody());
// print document
Zend_Debug::dump($document);
Een document aanpassen gebeurt door een PUT-request met als parameter in de URL van de service het unieke ID van het record dat wordt ge-updated:
// get document
$response = $client->restGet('test/c447a8366d74d880f35720d92d68419e');
// un-Json-ize document
$document = Zend_Json::decode($response->getBody());
// change values
$document['title'] = '"updated title!"';
// update document
$response = $client->restPut('test/c447a8366d74d880f35720d92d68419e', Zend_Json::encode($document));
// print response
Zend_Debug::dump($response);
Deze response geeft terug een “201 – Created” weer met dezelfde unieke documentID. Hier is het revisienummer echter van 1 naar 2 verhoogt.
object(Zend_Http_Response)#7 (5) {
["version:protected"] => string(3) "1.1"
["code:protected"] => int(201)
["message:protected"] => string(7) "Created"
["headers:protected"] => array(7) {
["Server"] => string(39) "CouchDB/0.10.0a773105 (Erlang OTP/R12B)"
["Location"] => string(59) "http://localhost:5984/test/c447a8366d74d880f35720d92d68419e"
["Etag"] => string(13) ""2-114293395""
["Date"] => string(29) "Tue, 19 May 2009 18:41:10 GMT"
["Content-type"] => string(24) "text/plain;charset=utf-8"
["Content-length"] => string(2) "72"
["Cache-control"] => string(15) "must-revalidate"
}
["body:protected"] => string(72) "{"ok":true,"id":"c447a8366d74d880f35720d92d68419e","rev":"2-114293395"}
"
}
CouchDB zorgt dus zelf voor versionering van de documenten in de database! Dit betekent dat je op ieder moment een document terug kunt halen uit de database. Ook indien een document werd verwijderd kan een document terug worden gevonden om eventueel te gaan herstellen. (verwijderen betekent voor CouchDB intern dus eigenlijk een nieuwe (niet toegankelijke) versie aanmaken)
Een ander groot voordeel van een objectgeoriënteerde database als CouchDb is dat je eender welk document kunt opslaan. Je moet immers niet op voorhand, zoals bij vb. Mysql, een databaseschema gaan opmaken om zo de structuur van je database vast te leggen. Dit betekent ook dat je een document waarvan je de structuur hebt aangepast zonder problemen kunt aanpassen en bijwerken. Aanpassingen aan de structuur van objecten (vb. een blog-entry krijgt een extra veld bij: summary) vereisen in dat geval geen aanpassingen aan de database.
Get on with it! >> http://couchdb.apache.org/
Source code van deze voorbeelden vind je via GitHub: http://github.com/FabriZZio/couchdb-zend-rest/tree/master
Alle recente projecten van Marlon maken gebruik van open source frameworks. Zowel voor .NET als PHP zijn er heel wat alternatieven beschikbaar. Voor PHP zijn er de frameworks als Symfony, Zend Framework en eZComponents maar ook minder algemeen gekende parels als Spoon Library.
Een framework kan je zien als een bouwdoos waarmee je je applicatie gaat bouwen. Een extra laag tussen de programmeertaal (vb. PHP) en je eigen geïmplementeerde functionaliteit. Een goed framework voorziet in een basis voor applicaties en zorgt ervoor dat je als ontwikkelaar niet steeds opnieuw het spreekwoordelijke wiel moet gaan uitvinden.
Ieder framework of library heeft ongetwijfeld zijn voor- en nadelen, net zoals iedere programmeertaal dat heeft. Google is uw vriend als je voor het slapengaan voor jezelf wilt uitmaken welk framework nu eigenlijk wel de beste is.
Naast snelheid en betrouwbaarheid stelden wij één uitermate belangrijk aandachtspunt voorop bij de keuze van een framework: uitbreidbaarheid. Hoe uitgebreid een specifiek framework ook mag zijn, wanneer je websites op maat ontwikkelt zal er altijd wel één of andere component zijn dat je niet zomaar uit de bibliotheek kunt pikken. Daarom is het van het allergrootste belang dat een framework uitbreidbaar is. Een ontwikkelaar moet eenvoudig (en dus ook snel) bestaande functionaliteit kunnen uitbreiden om zo aan projectspecifieke eisen te kunnen voldoen. (denk “extends”, “implements”, …)
Voor enkele recente projecten maakten we gebruik van het Zend Framework. Naast de verschillende mogelijkheden om het bestaande framework uit te breiden kunnen we hier ook rekenen op een erg uitgebreide documentatie en een levendige community.
Iedere webontwikkelaar met een beetje eergevoel wil alles altijd zelf programmeren. Onze ervaring leert echter dat het voor beide partijen de beste keuze is om zoveel mogelijk tijd en energie te steken in projectspecifieke functionaliteit en gebruik te maken van de basisfunctionaliteit van een framework.
Dit betekent echter niet dat je het framework van je keuze als een zwarte doos moet gaan beschouwen. Zoals bij alle mogelijke problemen die je tijdens het verloop van een project tegen het lijf loopt geldt ook hier dat je moet blijven nadenken. Neem nooit iets “zomaar” aan. Ga na en controleer hoe het komt dat iets op een bepaalde manier werkt. Ga je daarmee als team akkoord, doe het dan op die manier. Doe je dat niet, argumenteer waarom en los het probleem op je eigen manier op. Met een beetje geluk kan je de reeds bestaande functionaliteit alsnog uitbreiden en met minimale inspanning en tijd het gewenste resultaat bereiken!