Ga naar hoofdinhoud
AcademytutorialBouw een Nextcloud-app op de Conduction-stack, Deel 0: Drie paden, één leerlijn

Bouw een Nextcloud-app op de Conduction-stack, Deel 0: Drie paden, één leerlijn

Voor je een regel code schrijft, bepaal welk van de drie Conduction app-bouwpaden past bij de app die je in gedachten hebt. Traditioneel Nextcloud, OpenRegister + nextcloud-vue, of volledige manifest. Elk pad bouwt voort op wat het vorige je geeft, en de rest van de DeskDesk-serie leert het manifest-pad omdat dáár de curve steil in ons voordeel buigt.

TutorialApp developmentArchitectureOpenRegisternextcloud-vueManifestTutorial series
10 min read

Dit is Deel 0 van de zesdelige DeskDesk-tutorial, de oriëntatieronde. Voor scaffolds, schema's of manifests is het nuttigste dat we een nieuwe ontwikkelaar kunnen geven een eerlijke kaart van de drie manieren waarop Conduction-apps daadwerkelijk gebouwd worden, wat elk pad kost, en wat elk pad teruggeeft. De rest van de serie kiest één pad en laat de bonnetjes zien. Deel 0 legt uit waarom.

Iets anders is al vanaf minuut één belangrijk: het manifest-systeem en de @conduction/nextcloud-vue componentenbibliotheek zijn twee verschillende oppervlakken. Het manifest is de declaratieve wat, één manifest.json die navigatie, pagina's en configuratie beschrijft. nextcloud-vue is de rendering hoe, de Cn*-componenten waar het manifest naartoe dispatcht (CnAppRoot, CnPageRenderer, CnIndexPage, CnDetailPage, CnDashboardPage, en de rest). Technisch zijn ze los te koppelen. In de praktijk zijn ze zo verweven dat de rest van deze serie ze samen leert, en elke les noemt welk oppervlak hij aanraakt.

De drie paden in één oogopslag

Dezelfde DeskDesk-feature, een lijst met bureaus met een detailpagina, een boekingsdialoog, en een sidebar die audit-historie toont, kan op drie manieren gebouwd worden. Kies de tabelcel die klinkt als jouw team.

Pad 1: Traditioneel NextcloudPad 2: OpenRegister + nextcloud-vuePad 3: Manifest + nextcloud-vue
Wat je schrijftPHP-controllers, Doctrine entities + migraties, handgemaakte Vue-views, eigen routes, je eigen CRUD-endpointsSchema's in JSON, register-configuratie, handgemaakte Vue-views opgebouwd uit Cn*-componenten, je eigen App.vue + routerSchema's in JSON, één manifest.json die pagina's + config beschrijft, alleen de echt-maatwerk-views als type: 'custom'
Per-app code voor de DeskDesk-feature hierboven~1500 LOC~600 LOC~30 LOC + het manifest
Waar de data leeftApp-private databasetabellen die je zelf hebt gedefinieerdEen gedeeld OpenRegister-register, elke andere app op dezelfde Nextcloud kan via de registry lezen/schrijvenHetzelfde als Pad 2
RBAC, audit log, GraphQL, cross-app-referenties, bestandsbijlagen, calendar/contacts-integratiesBouw elk zelfGratis, OpenRegister levert ze mee. Zie "Wat OpenRegister je hoe dan ook geeft" hieronderGratis, hetzelfde als Pad 2
Lijstpagina's, detailpagina's, filter-sidebars, mass-action-dialogenBouw elk zelfHergebruik CnIndexPage, CnDetailPage, CnDashboardPage, schema stuurt kolommen en formulierenHergebruik dezelfde componenten, declaratief gedispatcht door CnPageRenderer vanuit je manifest.json
Een priority-veld toevoegen aan bookingsNieuwe migratie, nieuwe controller-code, nieuw Vue-veld, nieuwe validatieVeld toevoegen aan schema → formulieren en tabellen pikken het automatisch opHetzelfde als Pad 2, schema-gedreven door en door
Een kanban-bord toevoegen (echt maatwerk)Bouw hetBouw het als Vue-component, mount het in je routerBouw het als Vue-component, declareer {type:'custom', component:'PipelineBoard'} in het manifest
Onderhoudslast over 10 vergelijkbare appsElke app drift weg. 10 lijstpagina's, 10 detailpagina's, allemaal net iets anders.Het Vue-oppervlak drift nog steeds, elke App.vue en router is handgeschreven. Schema-migraties blijven schoon.Eén manifest-vorm over de hele vloot. Een lib-bump fixt elke app tegelijk.
Leercurve tot eerste werkende paginaLaagst als je al Nextcloud-app-ontwikkeling kent. De patronen zijn gedocumenteerd.Middelmatig, schema's + Cn*-componenten zijn nieuw maar goed uitgesleten.Steilst in het begin, je moet eerst manifest-dispatch doorgronden. Na Deel 2 keert de curve om.
PlafondWat je in PHP + Vue kunt bouwen. Geen plafond maar ook geen hefboom.Schema-gedreven CRUD schaalt prachtig. Maatwerkflows zijn nog steeds handgemaakte Vue.Hetzelfde als Pad 2 plus: elke Conduction-app upgrade samen wanneer het manifest-schema of nextcloud-vue evolueert.

Wanneer welk pad de juiste keuze is

Pad 1, Traditioneel Nextcloud is de juiste keuze wanneer:

  • Je een Nextcloud-native feature levert zonder gebruik van cross-app gedeelde data (bijv. een Talk-command-extensie, een OAuth-provider, een calendar-provider-plugin).
  • Je gedrag nodig hebt dat onder de datalaag leeft, file storage-hooks, dav-endpoints, sharing-extensies.
  • Je een legacy-app onderhoudt waarvan de patronen ouder zijn dan OpenRegister en een herschrijving niet te rechtvaardigen is.
  • Je expliciet de vrijheid nodig hebt om af te wijken van de Conduction-stack, bring-your-own-database, bring-your-own-frontend-framework, alles waar de beperkingen je zouden vertragen.

Pad 2, OpenRegister + nextcloud-vue is de juiste keuze wanneer:

  • Je data fundamenteel CRUD is tegen een kleine set schema's, maar je de paginacompositie voorlopig handgeschreven wilt houden, misschien omdat de bestaande app al een eigen App.vue heeft, of omdat je incrementeel wilt migreren.
  • Je aan het prototypen bent en eerst een paar handgemaakte views wilt voelen voor je commit aan een manifest-gedreven vorm.
  • Het team de manifest-mechanica nog niet heeft geleerd en je een deadline hebt.

Pad 3, Manifest + nextcloud-vue is de juiste keuze wanneer:

  • De app voornamelijk een verzameling register-backed CRUD-oppervlakken is met een paar maatwerkflows erbovenop, wat de overgrote meerderheid van Conduction-apps beschrijft.
  • Je de app op de upgrade-trein wilt houden: lib-bumps, schema-verbeteringen, toegankelijkheidsverbeteringen stromen binnen zonder per-app-werk.
  • Je vers begint. De totale tijd tot een werkende app op Pad 3 is minder dan op Pad 2 zodra je het één keer hebt gedaan, ook al is het eerste uur steiler.
  • Je de navigatie wilt kunnen herontwerpen, een lijst voor een dashboard wilt wisselen, of een wiki-sectie wilt toevoegen door JSON te bewerken in plaats van Vue te herschrijven.

De DeskDesk-tutorialserie leert Pad 3. Deel 1 legt het chassis. Deel 2 introduceert het manifest. Deel 3 laat zien hoe één schema-annotatie boekingen in Nextcloud Calendar laat verschijnen zonder lijmcode. Deel 4 voegt een kennis-sidebar toe gevoed vanuit xWiki en levert de app op.

Wat OpenRegister je hoe dan ook geeft, ongeacht het pad

Dit onderdeel verrast mensen. OpenRegister is niet zomaar "een register met CRUD-endpoints", het is een dataplatform dat een aantal Nextcloud-native superkrachten meelevert op het moment dat je er een schema in stopt. Of je nu op Pad 2 of Pad 3 bouwt, je erft dit allemaal zonder het te schrijven:

Pad 2 en Pad 3 bouwen beide op dit fundament. Pad 1 niet, elk van de bullets hierboven is een apart engineering-project als je vanaf rauw Nextcloud begint.

Twee oppervlakken, één leerlijn

Een veelvoorkomende verwarring bij het lezen van de rest van deze serie: het manifest is niet hetzelfde als de componentenbibliotheek, ook al leren we ze samen.

  • Het manifest is src/manifest.json. Het is een JSON-document gevalideerd door een schema (https://raw.githubusercontent.com/ConductionNL/nextcloud-vue/main/src/schemas/app-manifest-v2.schema.json, op dit moment versie 2.7.0). Het beschrijft navigatie-entries, routes, en wat elke pagina rendert. Het heeft op zichzelf geen runtime-gedrag.
  • De componentenbibliotheek is @conduction/nextcloud-vue. Het is een set Vue 2-componenten met de prefix Cn*, CnAppRoot mount de app-shell, CnPageRenderer leest het manifest en dispatcht de juiste paginacomponent, CnIndexPage/CnDetailPage/CnDashboardPage renderen de daadwerkelijke pagina-oppervlakken.

Je kunt de bibliotheek gebruiken zonder het manifest. Pad 2 in de tabel hierboven doet precies dat, een handgemaakte App.vue mount Cn*-componenten direct in een handgeschreven router. Je schrijft meer Vue, maar je houdt het schema-gedreven listing/detail/form-gedrag en je houdt alle OpenRegister-perks.

Je kunt het manifest niet gebruiken zonder de bibliotheek. Het manifest is betekenisloos totdat iets het leest, CnPageRenderer is dat iets. Dus het manifest-pad is altijd een manifest + bibliotheek-leerlijn.

De implicatie voor hoe je deze serie leest:

LesManifest-oppervlakBibliotheek-oppervlak
Deel 1: Scaffoldnog geenCnAppRoot-chassis
Deel 2: Schema's + manifestintroduceer manifest.json, page types, config-propsCnPageRenderer-dispatch, CnIndexPage + CnDetailPage props
Deel 3: Schema-gedreven integratiesonveranderdcalendar-provider-annotatie stroomt door CnDetailGrid
Deel 4: Knowledge-tab + shipsidebar-tabs in config.sidebar, type: 'custom' voor de wiki-viewhost-app SFC geregistreerd als custom component, CnObjectSidebar consumeert manifest-tabs

Als je maar één ding onthoudt over de relatie: het manifest beantwoordt "wat moet deze app renderen"; de bibliotheek beantwoordt "hoe wordt dat gerenderd". De bibliotheek maakt het manifest levend.

Een notitie over één keer kiezen versus later kiezen

Je hoeft niet voor altijd een pad te kiezen. Apps bewegen routinematig tussen Pad 2 en Pad 3, een aantal Conduction-apps begon op Pad 2 en verhuisde naar Pad 3 zodra het team het manifest leerde. De migratie is meestal 1 tot 2 dagen voor een app met 5 tot 10 schema's, omdat de schema's helemaal niet veranderen; alleen App.vue + de router worden vervangen door CnAppRoot + een manifest.

Van Pad 1 naar Pad 2 of Pad 3 gaan is moeilijker omdat je de datalaag naar een register moet migreren. Plan dat als een echt project, niet als een refactor tussen sprints door.

Waar nu naartoe

Volgende stappen