A-stad: een mix van krachtige, nieuwe front- en backend technologieën

Post on 13-Apr-2017

851 views 2 download

Transcript of A-stad: een mix van krachtige, nieuwe front- en backend technologieën

10/09/15A-stad meetup

Kris Waelkens

Analyst

Dries Droesbeke

Architect

Jan-Bart Vervoort

Back-end Dev

Mante Bridts

Front-end Dev

Charlie Misonne

Testing

■wifi: ‘DigAnt Free Wifi’■hashtag: #digantcafe■instagram: @digipolis_antwerpen■twitter: @dgplsantwerpen■slideshare:

http://www.slideshare.net/digipolisantwerpen

■linkedin: https://www.linkedin.com/company/digipolis

■facebook: https://www.facebook.com/Digipolis/

Some info

What? Why?A-stad

Centrale Referentie Systemen

burger / medewerker

...

So it begins...

Concept

mei ‘14: release beta.antwerpen.be

Centrale Referentie Systemen

burger

Centrale Referentie Systemen

A-profiel (user app)

meldingene-loket notificati

on redactie ... helpcenter

cart(betalen) search stadspla

n

burger

no comment

Centrale Referentie Systemen

A-profiel (user app)

e-loket notification redactie ... helpcent

ercart

(betalen) search stadsplan

burger

meldingen

navoor

Centrale Referentie Systemen

A-profiel (user app)

meldingene-loket notificati

on redactie ... helpcenter

cart(betalen) search stadspla

n

burger

Centrale Referentie Systemen

A-profiel (user app)

meldingene-loket notificati

on redactie ... helpcenter

vacatures

contact-boek

Onboarding

medewerker

Centrale Referentie Systemen

A-profiel (user app)

meldingene-loket notificati

on redactie ... helpcenter

cart(betalen) search stadspla

n

burger

API’s

Work in progress:

■API’s & SDK: developer portal■Challenge: zero downtime deployment■Reusable backend “engines”-> Antwerp City Platform as a Service (AcPaaS)-> Check http://antwerpen.digipolis.be!!!

Work in progress...

Overview architectureA-stad

Overview

Frontend

Backend

Databases

Integrations

Infrastructure

ALM

Tips■ automate everything from day 1■ use vagrant with production cookbooks■ create a skeleton with separate

packages(npm,bower,NuGet,composer)■ version your api’s/packages with semver■ code review with pull requests■ Write tests■ separation by isolation #(micro)services■ no agile excuses!

Backend@janbart

A-stad

vagrant up

vagrant up

pm2 start processes.json

pm2 start processes.json

Favorite

app.put('/srv/overzicht/d/items/:itemId/favorite', function(req, res) { var overviewItemId = req.params.itemId; var favorite = req.body.favorite; app.astad.acl.requireLogin(app, req, res, function() { var user = req.adata.user; var context = users.hasContext(req, "employee") ? "employee" : "user"; favorites.favoriteItem(user, context, overviewItemId, favorite, function(err, data) { if (err) {

return res.status(500).json(getError(err.message)); } else if (data == null) { return res.status(404).json(getError('Kon favoriet niet

vinden.')); } else { return res.json(getResponse(data)); } }); }, function() { return res.status(401).json(getNoPermission()); });

});

app.put('/srv/overzicht/d/items/:itemId/favorite', access.canFavorite(app), function(req, res) { var overviewItemId = req.params.itemId; var favorite = req.body.favorite; var user = req.adata.user; var context = users.hasContext(req, "employee") ? "employee" : "user"; favorites.favoriteItem(user, context, overviewItemId, favorite, function(err, data) { if (err) { return res.status(500).json(getError(err.message)); } else if (data == null) { return res.status(404).json(getError('Kon favoriet niet vinden.')); } else { return res.json(getResponse(data)); });});

/*** Save an item as favorite*/function favoriteItem(user, context, overviewItemId, favorite, callback) { var userId = user.id; async.waterfall([ function getOverviewObject(cb) { OverviewItem.findById(overviewItemId, cb); }, function userHasFavorites(overviewObject, cb) { if (overviewObject == null) { return cb(new Error('OverviewItem bestaat niet.')); } Favorite.findOne({userId: userId, context: context}, cb); }, function createFavoritesObjectIfNeeded(favoriteObject, cb) { if (favoriteObject == null) { if (favorite) { // Create favorite object for user return saveFavorite(userId, context, overviewItemId, function saved(err, data) { return favoriteSaved(err, data, overviewItemId, cb); }); } else { return cb(new Error("Dit item behoort nog niet tot je favorieten.")); } } else { var foundId = favoriteObject.overviewItemIds.indexOf(overviewItemId) !== -1; if (foundId) { if (favorite) { return cb(new Error("Je hebt dit item al toegevoegd aan je favorieten.")); } else { favoriteObject.overviewItemIds.pull(mongoose.Types.ObjectId(overviewItemId)); return favoriteObject.save(function saved(err, data) { return favoriteSaved(err, data, overviewItemId, cb); }); } } else { if (favorite) { favoriteObject.overviewItemIds.push(mongoose.Types.ObjectId(overviewItemId)); return favoriteObject.save(function saved(err, data) { return favoriteSaved(err, data, overviewItemId, cb); }); } else { return cb(new Error("Je moet dit item toevoegen aan je favorieten voordat je het kan verwijderen uit je favorieten.")); } } } } ], callback);}

/*** Save an item as favorite*/function favoriteItem(user, context, overviewItemId, favorite, callback) {

async.waterfall([ function getOverviewObject(cb) {}, function userHasFavorites(overviewObject, cb) {}, function createFavoritesObjectIfNeeded(favoriteObject, cb) {} ], callback);}

Test it.™

Node Package Manager

NPM

NPM-modules

Hi, I'm Betty.

Developer x

Developer x

Developer y

Developer z

Developer x

Developer 1

Developer 2

Front-end developmentA-stad

vagrant up

Minifying

JS hint Sass to css

Watch

Sprite generator

Concat

Strip & uglify

Bless

i18n

■API: styling API with variables, mixins, functions

■Base: styling for base HTML elements

■Grid: the Singularity grid■Helpers: definition of helper classes

Sass-kit

■Components:●Collections of HTML elements that form a new element together

●Directives

■Vendor: styling overrides for vendor components

Sass-kit

improvescode quality!

meldingen

A-kaart

notificationredactie

helpcenter

cart(betalen)

search

stadsplan

ui

user

contactboek

boodschap

vacature

meldingen

A-kaart

notificationredactie

helpcenter

cart(betalen)

search

stadsplan

ui

user

contactboek

boodschap

vacature

Single Point of Failure...

Contactboek app

Template

Service

Controller

$scope

Template

Controller

Service

Service

Service

Directives

<data-ng-if>

<data-ng-repeat>

<a>

Vragen?

Waarom en hoe automatiseren- Charlie Misonne

Automated RegressionTesting

Een verandering impacteert een voorheen werkend systeem op een negatieve manier

Wat is regressie

Testautomatisatie - algemeen

Agile? ⇒ Automatiseer!

Korte sprintsSnelle releasesContinuous integration

Waarom?

Verschillende niveaus

Begin onderaan!

5min

10min

90min

... uren, dagen??

UI test-automatisatie!

■Repetitieve testen?

■Regressie testen = repetitief⇒ Ideaal voor automatisatie!

Wanneer UI automatisatie?

Automation paradox

Veel veranderingen

Veel regressietesten nodig Automatisatie is moeilijk

Demo...

Protractor vs. Selenium...

SeleniumWebdriver

■Angular Locatorselement(by.binding('item.assignee.fullName'))element(by.repeater('answer in question.answers'))

■Wacht op page sync ($timeout, $http)

■A-stad technologieën

Waarom Protractor?

Demo...

Protractor