De07
TheNERDstuff:openingDominotothe
modernwebdeveloper
JanKrejcarek
PPFbanka(CZ)
@jan_krejcarek
OliverBusse
We4IT(D)
@zeromancer1972
Agenda
Spoiler:NERD=Node.js,Express,React,Domino
Node.jsintroduction
AppDevPack
Proton,DesignCatalog&DQL
Development,Testing,Deployment
CRUDdemo
Securityoptions
GettingHelp
Resume:why?
Q&A
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Node.jsintroduction
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Node.jsisNOTaserver
Butyoucancodeone
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Simplestserverexample
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.write(new Date().toISOString());
res.end();
});
server.listen({port:8080}, () => {
console.log("listening")
});
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
FrameworksforNode.jswebapps
Express
Koa
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Expressbasicprinciple
Codefortheendpoint:
router.get('/certificates/expiring/:someDate?', async (req, res, next) => {
let d = null;
if (typeof req.params.someDate != 'undefined') {
d = parse(req.params.someDate);
} else {
d = addMonths(endOfDay(new Date()), 3);
}
try {
var docs = await dao.getCertificatesExpiringBefore(d);
res.json(docs);
} catch (error) {
res.status(500).json({error:error.message})
}
})
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DominoAppDevPack
Standalonedistribution(partnumberCC0NGEN)
NotpartoftheNotes/Dominoinstallationpackage
NotsupportedinDominoDesigner(whichisgood)
AvailableforDominoonLinuxandWindows(sincev1.0.1,March26,2019)
Quarterlyreleases
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
ContentoftheAppDevPack
Protonservertask
DominoDBmoduleforNode.js(notavailableonnpmjs.org,yet)
Demoapplicationwithdata
Documentation
Installationprocedure
APIdocumentation
DominoQueryLanguagesyntax
IAMexamples
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Protonschema
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Protontaskinstallation
Copythe"proton"filetotheDominoprogramdirectory
Add"Proton"totheServerTasksvariableinnotes.initostarttheProton
taskwhenDominostarts
ConfiguretheProtonusingnotes.inivariables:
PROTON_LISTEN_ADDRESS=0.0.0.0
Listensonallavailablenetworkinterfaces
PROTON_LISTEN_PORT=30000
TCP/IPporttouse
PROTON_SSL=1
UseTLSforcommunication
PROTON_KEYFILE=server.kyr
CanbethesameDominoalreadyusesforTLS
PROTON_AUTHENTICATION=client_cert
AuthenticateNode.jsappsusingacertificate
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Recommendedsettingforproduction
Encryptthecommunication
Authenticateapplicationsusingacertificate
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Three‑tierarchitecture
BymovingapplicationlogictoNode.jsandthepresentationlogictothe
browserweareactuallymovingtoathree‑tierarchitecturewhereDomino
functionsasastorage
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Proton
Three‑tierarchitecture
Inthatcaseuserswillbeauthenticatedbytheapplicationlayer(Node.js)
andtheNode.jsapplicationwilluseanotheraccounttoaccessthedata
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Proton
Howitworks
ProtonseesNode.jsapplicationconnectingusingDominoDBmoduleasa
userwithcertainrights
Alloperationsondataareexecutedundertheauthorityofthisuser
ThisusersneedssufficientrightsintheACLofthedatabaseituses
ItistheNode.jsapplication'stasktoensurecorrectaccesstodatatoits
users
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Proton
Authenticatingusingacertificate
Node.jsapplicationusingDominoDBneedstohaveaPersondocumentin
theDominoDirectory
ItalsoneedsanX.509certificateandholdtheprivatekeytothatcertificate
ThecertificateneedstobeloadedtothePersondocument
ImportInternetCertificateactiononthePersondocument
ThenameinthePersondocumentmustcorrespondtothesubject's
commonnamefromthecertificate
TheuserneedstohaveaccesstothedatabaseviaACL
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Persondocumentfortheapplication
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
ACLrecordinthedatabase
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
RunningProton
commandontheDominoserverconsole:loadproton
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DesignCatalog,DQL
domino‑dbmoduleloadsacollectionofdocumentsbyrunningaDQL
query.
DesignCatalogisneededforDQLtoworkproperly.
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DesignCatalog,DQL
Addadatabasetothecatalog:
load updall <database path> -e
Updateadatabaseinthecatalogwhenthedesignchanges:
load updall <database path> -d
Whentheupdatefails:
runtheupdallagainwiththe‑eflag:
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DQLFacts1/3
DQLscansalimitednumberofdocumentsandviewentries(200000)
increaseitwithanotes.inisetting(systemwide)
QUERY_MAX_DOCS_SCANNED
QUERY_MAX_VIEW_ENTRIES_SCANNED
DQLqueryrunsforalimitedtime(2minutes)
rethinkyourdesign
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DQLFacts2/3
ProtonreturnstheresultssortedbyNoteIDandreturnsonlyasubsetofthe
results(max200).
Youhavetoloadallresultsandsortthemyourself
SortingshouldbeavailableinDomino11
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DQLFacts3/3
"Mindthegap"
DQLqueryneedsspacesaroundoperators,valuesanditemnames
'Cards'.Subtypes ='Beast'
ERR_BAD_REQUEST:Queryisnotunderstandable‑syntaxerror‑MUSThaveat
leastoneoperator
UsetheexplainQuery()methodtoanalyzeyourqueriesandoptimizethem
['Cards'.Subtypes = 'Beast' AND 'Cards'.ConvertedManaCost > 4]
0. AND (childct 2) (totals when complete:) Prep 0.0 msecs, Exec 71.428 msecs, Sc
1.'Cards'.Subtypes = 'Beast' View Column Search estimated cost = 5
Prep 0.326 msecs, Exec 3.506 msecs, ScannedDocs 0, Entries 248, FoundDocs
1.'Cards'.ConvertedManaCost > 4 View Column Search estimated cost = 10
Prep 0.112 msecs, Exec 67.915 msecs, ScannedDocs 0, Entries 4482, FoundDoc
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Settingupyourdevelopmentenvironment
(1)
InstallNode.jsruntime(Win,Mac,Linux)
Grabyourfavoriteeditor(VSCoderecommended)
Inittheproject
mkdir myProject
cd myProject
npm init
Addthedomino‑dbNodepackagetoyourproject
npm install <pathToAppDevPack>/domino-domino-db-1.2.0.tgz -save
Startcoding
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Settingupyourdevelopmentenvironment
(2)
Checkthepackage.jsonfile
itwillalreadycontainthedepencyfordomino/domino‑db
addotherdependencies
Createthestartjavascriptfile
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Testing?Sure!
Severalunittestpackagesavailable
Mocha
Tape
Chai
Sinon
Testsaredefinedinseparatefiles
Testsareconfiguredinthepackage.jsonfile
{
"test-unit": "NODE_ENV=test mocha '/**/*.spec.js'",
}
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Deployment(1)
Scenariostoconsider
deploytoacloudservicelikeAWS,Azure,IBMCloud,Heroku
deploytoon‑premisesenvironment
On‑premises
Doesyourserverhaveinternetaccesstoinstallpackages?
Doesyourserverutilizealoadbalancer?
Hotdeploymentornot?
UsingaDockercontainer?
Usingaproxylikenginx
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Deployment‑usingaproxy
AsNode.jsappscanusedifferentportsyoushouldutilizethemwitha
proxytokeeptheURLendpointssimple
nginxisalightweightproxyserverwhichiseasytosetup
# excerpt from nginx.conf
location /app1 {
proxy_pass http://localhost:3001/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /app2 {
proxy_pass http://localhost:3002/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Deployment‑ProcessManager(1)
Useaprocessmanagertohandleallyourapps
Donotstartyourappsmanuallyorwithasystemdscript/service
pm2ishighlyrecommended
Verysimpletosetup
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Deployment‑ProcessManager(2)
starttheappwiththeprocessmanager
pm2 start myApp.js
showallappsmanagedbypm2
pm2 ls
┌───────────────────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬──────┬
│ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │
├───────────────────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼──────┼
│ node alexa-node-red │ 11 │ N/A │ fork │ 24488 │ online │ 0 │ 2M │
│ node domino-node-list │ 9 │ N/A │ fork │ 24152 │ online │ 0 │ 2M │
│ node rootweb │ 10 │ N/A │ fork │ 24229 │ online │ 0 │ 2M │
│ node-red │ 0 │ N/A │ fork │ 5463 │ online │ 6 │ 49D │
└───────────────────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴──────┴
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Deployment‑ProcessManager(3)
savetheappstothelistofbootableapps
pm2 save
enablepm2tostartallsavedappsatboot
pm2 startup
AllcommandsarethesameonWin,Mac&Linux
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
domino‑dbmodule
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
domino‑dbclasses
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
domino‑dbmodule
providesfourbasicoperationswithdata‑Create,Read,Update,Delete
hasasingleentrypoint:userServer()function
const { useServer } = require('@domino/domino-db');
const server = await useServer({hostName: 'localhost', connection:{ port: '30000' }});
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
domino‑dbcommandlineexample
const { useServer } = require('@domino/domino-db');
const serverConfig = {hostName: 'localhost',connection:{ port: '30000'
const databaseConfig = { filePath: 'database/node-demo.nsf' };
(async function() {
try {
const server = await useServer(serverConfig);
const db = await server.useDatabase(databaseConfig);
const response = await db.bulkReadDocuments({
query: "'AllContacts'.State = 'FL'",
itemNames: ['LastFirstName', 'Email'],
computeOptions: { computeWithForm: true }
});
console.log(JSON.stringify(response));
} catch (error) {
console.log(`${error.code}: ${error.message}`)
}
})()
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
DEMO‑WebApplication
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
CRUDDetails
CalluseServer()andServer::useDatabase()onlyonceandcachethe
instancesinacustomDataAccessObject
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
CRUDDetails‑Create
Whencreatingadocument,youneedtoprovidethe"Form"property
WhenwritingaDateitem,youneedtospecifyitlikethis:
DueDate: { type: 'datetime', data: '2019-06-30'}
Timeneedstobespecifiedtoahundredthofasecond,youcan'tdirectly
useaJavaScriptDateobject
YoucanspecifycomputeOptionstocomputeitemsinthedocument
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
CRUDDetails‑Read
Youalwaysspecifywhichitemsyouwanttoreceive(keepstheamountof
transfereddatalow)
usecomputeOptionsparametertocomputethecontentofcomputedfor
displayitems
const response = await db.bulkReadDocuments({
query: "'AllContacts'.State = 'FL'",
itemNames: ['LastFirstName', 'Email'],
computeOptions: { computeWithForm: true }
});
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
CRUDDetails‑Update
Selectionofoptionsforupdatingdocuments
changeselecteditemsinoneormoredocumentsatonce
replaceallitemswithasetofotheritems
Documentsareimmediatelysaved,thereisnosave()method
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
SecurityOptions(1)
IAM(IdentityAccessManagement)enablesaccessfromaNode.jsappto
DominoasarealDNNuser
UsesOAuthmechanismtoauthorizeagainstDomino
Domino10providesOAuth(kindof)
Accessisrestrictedtocertainscopes
open_id
offline_access
das.freebusy
das.calendar.read.with.shared
das.calendar.write.with.shared
CurrentlyIAMdoesnotsupporttheNode.jsAPIforDomino,onlyDAS:‑(
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
SecurityOptions(2)
SetupDominoasanOAuthprovideristimeconsuming(expect1workday)
Youwillneedtotouchthefollowingareasof(Domino)administration
Certificatehandling
Keyringgeneration
DominowithSSL
DominoLDAPconfiguration
OAuthDSAPIsetup
SetuptheIAMserviceapp(serverpart)
CustomizetheIAMserviceapp(optional)
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
SecurityOptions(3)
IAMcomeswithexamplesofdifferentauthorizationflows
AuthorizationCodeFlow
ClientCredentialFlow
Theseexamplescanbeusedtointegratethosemechanismtoyourown
app(i.e.IAMclientapp)
AppsmustberegisteredwiththeIAMserviceapp(generatestheappID
andtheappsecret)
YouareresponsibleforthetokenhandlingwhenaccessingtheDomino
server!
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
GettingHelp/Resume:why?
NERDiscompletelydifferentfromtraditionalNotesdevelopment
Gettinghelp
DominowithNodeisdiscussedintheOpenNTFSlackchanneldominonodejs
ReachoutfortheexpertslikeDanDumont,PeiSunorHeikoVoigt(allactiveon
Slack)
Whyyoushoulduseit?
ItopensDominoforthemodernwebdeveloper(newbloodforthebestapp
serverintheworld)
OfferstonsofnewpossibilitiescomingwithvariousNodemodulesandplugins
Usinge.g.Node‑REDdirectstothereallow‑codearea‑butthisiscontentfor
separatesessions;‑)
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Q&A
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Resources
WebinarDQL&FAQ:https://www.ibm.com/blogs/collaboration‑solutions/2019/02/04/domino‑query‑language‑faq
DominoAppDevPackDocumentation:https://doc.cwpcollaboration.com/appdevpack/docs/en/homepage.html
VisualStudioCodeEditor:https://code.visualstudio.com/
UnittestingandTDDinNode.js:https://www.codementor.io/davidtang/unit‑testing‑and‑tdd‑in‑node‑js‑part‑1‑8t714s877
Node.jsUnitTesting:https://blog.risingstack.com/node‑hero‑node‑js‑unit‑testing‑tutorial/
Nginxwebserver:https://nginx.org/en/docs/
pm2processmanager:https://pm2.io/runtime/
StackOverflowNode.js:https://stackoverflow.com/questions/tagged/node.js
OpenNTFSlack:https://slackin.openntf.org/
Node‑RED:https://nodered.org/
SessionRepo:https://gitlab.com/obusse/engage‑2019
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)
Engage2019‑TheNERDstuff:openingDominotothemodernwebdeveloper(De07)

The NERD stuff - opening for Domino to the modern web developer