Umbraco-CMS icon indicating copy to clipboard operation
Umbraco-CMS copied to clipboard

Implement new backoffice installer

Open nikolajlauridsen opened this issue 2 years ago • 0 comments

Note This is an early WIP, and is set not to be packable since we don't want to release this yet. There will be breaking changes in these projects

New backoffice installer

This is the initial suggestion for how the installer will work in the new backoffice, it uses the old installer as a starting point, however, most things have changed quite a bit. Additionally, since this is the first element of the new backoffice API there's quite a bit of setup code in this PR.

Project structure

Since the new backoffice API is still very much a work in progress I've created new projects for the new backoffice API:

  • Umbrao.Cms.ManagementApi - The "presentation layer" for the management API
  • "New" versions of existing projects, should be merged with the existing projects when the new API is released:
    • Umbraco.New.Cms.Core
    • Umbraco.New.Cms.Infrastructure
    • Umbraco.New.Cms.Web.Common

This also means that we have to use "InternalsVisibleTo" for the new projects since these should be able to access the internal classes since they will when they get merged.

General structure

Some generalities have been decided (for now at least).

Attribute routing

The new APIs will use attribute routing, along with API versioning, this allows us to do two things:

  • Automatically generate schemas and swagger docs for the endpoints, which can be used by the frontend
  • Update our endpoints without causing breaking changes, since we can create a new endpoint version and deprecate the old.

Attribute routing did however present a problem, how do we map to the backoffice route (default /umbraco), since that can be changed in configuration? To solve this I've created a custom routing token using an application model convention, this means that in the route attribute you can use [umbracoBackoffice], the same as using [controller], I.E: [Route("[umbracoBackoffice]/[Controller]/[Action]")]. This seemed like it might become tiresome in the long run though, and if the token name were to change things would break, so I've further wrapped it in a custom route attribute: BackofficeRoute, which prefixes the route with the backoffice token using a constant.

ViewModels

All the endpoints that require data from the frontend accept this as ViewModels, instead of domain models (how it is now), these view models are then mapped to domain models in the controller. While this might seem like additional work it serves to further decouple the APIs from the frontend, and furthermore the presentation layer from the rest of the system, essentially the frontend and backend no longer have to agree on how the data should be structured.

The installer

For the installer itself, this has been massively simplified, previously, the backend would be in charge of what view should be shown, and in what order, this is no longer the case.

The installer is now just a regular REST endpoint that takes a model with the necessary data, how the frontend gets this data is completely out of the backend's hands.

Additionally in the old installer. install steps could specify that they would restart the runtime, however, none of them did, and with the change to dotnet core, this is generally not necessary, we only do it once when the install is complete, mostly to update the runtime state.

The order of the install steps is also no longer specified by an attribute with a number, instead, an ordered collection is used.

The last larger change is that the new installer separates install steps and upgrade steps, this means that the InstallationType, is no longer used, instead install steps will implement IInstallStep, and upgrade steps will implement IUpgradeStep, if a step is both, it will implement both. There will then be two collections, one for install steps, and one for upgrade steps, and again if a step is both, it'll be added to both collections.

Testing

If you want to test out the new API you first have to add a couple of project references, since it by default isn't included:

Add this to Umbraco.Cms.csproj and Umbraco.Web.BackOffice.csproj

<ProjectReference Include="..\Umbraco.Cms.ManagementApi\Umbraco.Cms.ManagementApi.csproj" />

Now the composer will run and the new API will be available.

Sample payloads

/umbraco/api/v1.0/install/setup

{
  "user": {
      "name": "A.N Other",
      "email": "[email protected]",
      "password": "testproject",
      "telemetryLevel": "Basic"
  },
  "database": {
    "Name": "Umbraco",
    "providerName": "Microsoft.Data.SQLite",
    "id": "530386a2-b219-4d5f-b68c-b965e14c9ac9"
  },
  "subscribeToNewsletter": false
}

/umbraco/api/v1.0/install/validateDatabase

{
	"useIntegratedAuthentication": true,
	"id": "5e1ad149-1951-4b74-90bf-2ac2aada9e73",
	"providerName": "Microsoft.Data.SqlClient",
	"name": "NewInstaller",
	"server": ".\\SQLEXPRESS"
}

TODO

Testing is still needed, in particular, we need to find a way to ensure that the API follows the required schema

nikolajlauridsen avatar Aug 05 '22 08:08 nikolajlauridsen