Strapi 3 to Strapi 4 migration

January 31, 2022 admin 0 Comments

Strapi 3 to Strapi 4 migration – key differences and automation scripts

Straipi headless CMS has progressed quite well over the time and Strapi version 4 is a leap that redefines the way headless CMS are developed.

The latest version of strapi 3.x is a progressive development and has quite few things that needed redoing in a better way. Strapi4 is a complete rethink and rectifies the legacy issues with core structures and definition models defined by strapi3.

The upgrade across minor version of strapi 3.x were little less hectic where code was relatively easier while database still was somehow glitchy. The upgrade from strapi three to four potentially is lot of work where everything from data models, routes, policies, lifecycle events, controllers all have changed quite drastically.

The Upgrade requires conversion in almost every area of the implementation that is schema definitions within API, components, and extensions along with their lifecycle event handlers. Custom routes conversion to either old style routes or new modern

Update: Where we are with our automated migration

By today 07 April 2022 We have successfully migrated the complete content
type schemas, controllers, services, routes, policies, lifecycles with large
accuracy. We are currently testing this and generating MySQL database migration
scripts from strapi 3x to strapi 4.1.x versions.

the script is published at https://github.com/eharain/strapi3to4migration  
please download, correct the directories, in index.js, install fresh instance
of strapi4 and run migration script it will generate the necessary files in new
instance of strapi 4 , open the snapshot directory and run the MYSAL migration
script and your migration is done. double check the migrated code files
specially the js files and you are all done. readme is here https://github.com/eharain/strapi3to4migration/tree/master#readme

please let us know if you need any help.

The Directory Structure

The directory structure of the strapi 4 is quite changed from previous one. The extensions, plugin, components and api directories are moved under source directory called src.

The api entity directory structure has also changed, this includes the naming as well

The schema files are now moved deeper under content types and lifecycle events are declared in lifecycle JavaScript file. The routes are now split between custom routes and core routes the custom routes are quite similar to routes json file.

Schema definitions

Strapi 4 Schema definitions have changed significantly as compared to strapi 3.

The biggest impact is on relations where new relations declaration is much more sensible and defines it quite clearly what kind of relation it is as compared to earlier definitions.

Schema info

Unlike strapi 2 the info element in strapi 4 has name replaced with singular, plural and display names making the naming quite clear

Private attribute for a property.

In strapi 4 the attributes are now marked private under options in a list not as property of the actual attribute

Relations definition

In strapi 4 the relations are now marked as one to one and many term that makes it very readable and clear while in strapi 3 this model property was indicating one and collection was indicating many sides of the relation. Similarly, via and dominant property was indicating the bidirectional relations where in strapi 4 this is now clearer with mapped by and inversed by properties.

the model and collection are replaced with new attribute target the relations is indicated by clear relation types.


the target names are prefixed with namespace that API, plugin and admin with group and model names.

Files and media

There are changes in model file to media plugin relation as reference.

Model Components

The components names are now prefixed with their group names and their actual definition stays quite consistent to entity schemas.

Routes

The routes are now split between custom routes and core routes the custom routes are quite similar to routes json file of strapi 3 except it now is In JavaScript object format and exported as a module.

Services, Controllers and Policies are similar except with context changes and the object references so would require code reviews and testing for their implementations. the lifecycle also has minor variations that will need code review and in some cases re writes.

The configurations and plugin configurations also have changes along with the overall strapi modules and plugins moved to @strapi directory and will require appropriate changes.

Migrating the entities to strapi version 4

Due to the amount of difference between versions the migration approach we have adapted it by installing a fresh instance of strapi 4 instance. We have generated a script that will iterate the entries under api, components and extension directories under strapi 3 installation and generate new schema files in strapi 4 under its new format and naming convention. These schema definition and routes are converted quite reliably the other code files will need visual inspection; we will publish our finding as we go through this process bit more in detail.

Moving the Data from strapi v3 to strapi v4 database.

There are two separate approaches that can be taken to migrate the data the fastest of these is moving data within database engines with necessary transformation and the other approach is to request data from strapi 3 api and submit it to strapi 4 instance and both the approaches have some pros and cons. For the migrations we have performed so far, we have adapted the approach of moving data across databases.

// Following script should generate queries to generate queries for migrating the core entities and link tables except many to many relations.

SET
SESSION group_concat_max_len =
1000000;

SELECT
concat(‘ TRUNCATE TABLE ‘,TABLE_SCHEMA_D,‘.’,TABLE_NAME_D,‘; ‘,‘ INSERT INTO ‘,TABLE_SCHEMA_D,‘.’,TABLE_NAME_D,
‘(‘,COLUMN_NAMES,‘)’
,
‘ SELECT ‘,COLUMN_NAMES ,‘ FROM ‘,TABLE_SCHEMA_S,‘.’,TABLE_NAME_S,‘;’
)
as Q

FROM


(SELECT c.TABLE_SCHEMA_S, c.TABLE_SCHEMA_D,c.TABLE_NAME_S,c.TABLE_NAME_D,GROUP_CONCAT(c.COLUMN_NAME) COLUMN_NAMES FROM


(SELECT
DISTINCT    a.TABLE_SCHEMA TABLE_SCHEMA_S, b.TABLE_SCHEMA TABLE_SCHEMA_D, a.TABLE_NAME TABLE_NAME_S, b.TABLE_NAME TABLE_NAME_D,b.COLUMN_NAME FROM information_schema.COLUMNS a


INNER
JOIN information_schema.COLUMNS b ON a.TABLE_NAME = b.TABLE_NAME AND a.COLUMN_NAME = b.COLUMN_NAME


WHERE a.TABLE_SCHEMA =
‘strapi3_db_name’
AND b.TABLE_SCHEMA =
‘strapi4_db_name’) c GROUP
BY c.TABLE_NAME_S) d;

// Following script will generate queries for transferring the data to link tables. You will have to add entity id manually to the queries.

SELECT
concat(‘ TRUNCATE TABLE ‘,TABLE_SCHEMA_D,‘.’,TABLE_NAME_D,‘; ‘,
‘ INSERT INTO ‘,TABLE_SCHEMA_D,‘.’,TABLE_NAME_D,
‘(‘,COLUMN_NAMES,‘)’
,
‘ SELECT ‘,COLUMN_NAMES ,‘ FROM ‘,TABLE_SCHEMA_S,‘.’,TABLE_NAME_S,‘;’
)
as Q

FROM


(SELECT c.TABLE_SCHEMA_S, c.TABLE_SCHEMA_D, c.TABLE_NAME_S, c.TABLE_NAME_D, GROUP_CONCAT(c.COLUMN_NAME) COLUMN_NAMES FROM


(SELECT
DISTINCT    a.TABLE_SCHEMA TABLE_SCHEMA_S, b.TABLE_SCHEMA TABLE_SCHEMA_D, a.TABLE_NAME TABLE_NAME_S, b.TABLE_NAME TABLE_NAME_D, b.COLUMN_NAME


FROM information_schema.COLUMNS a


INNER
JOIN information_schema.COLUMNS b ON
REPLACE(a.TABLE_NAME,‘__’,‘_’)
=substring(b.TABLE_NAME,1,Char_length(b.TABLE_NAME)-6)
— SUBSTRING(b.TABLE_NAME,-6) — REPLACE(b.TABLE_NAME,’_links’,”)


AND a.COLUMN_NAME = b.COLUMN_NAME


WHERE a.TABLE_SCHEMA =
‘strapi3_db_name’
AND b.TABLE_SCHEMA =
‘strapi4_db_name’) c GROUP
BY c.TABLE_NAME_D) d;

// Following query will transfer the files and file morphs data to new files tables from upload file tables

USE strapi4_db_name;

SET FOREIGN_KEY_CHECKS=0;


TRUNCATE
TABLE strapi4_db_name.`files`;
TRUNCATE
TABLE strapi4_db_name.`files_related_morphs`;


INSERT
INTO strapi4_db_name.`files` (`id`, `name`, `alternative_text`, `caption`, `width`, `height`, `formats`, `hash`, `ext`, `mime`, `size`, `url`, `preview_url`, `provider`, `provider_metadata`, `created_at`, `updated_at`, `created_by_id`, `updated_by_id`)


SELECT `id`, `name`, `alternativeText`, `caption`, `width`, `height`, `formats`, `hash`, `ext`, `mime`, `size`, `url`, `previewUrl`, `provider`, `provider_metadata`, `created_at`, `updated_at`,
NULL `created_by`,
NULL `updated_by`


FROM strapi3_db_name.`upload_file`;


INSERT
INTO strapi4_db_name.`files_related_morphs`(`file_id`,`related_id`,`related_type`,`field`,`order`)


SELECT `upload_file_id`, `related_id`, `related_type`, `field`, `order` FROM `strapi3_db_name`.`upload_file_morph`


INNER
JOIN `strapi3_db_name`.`upload_file` ON `strapi3_db_name`.`upload_file`.id=`strapi3_db_name`.`upload_file_morph`.upload_file_id ;

Customise following query for your needs and cover your components and entities names to correct relations of files to the entities.

UPDATE strapi4_db_name.`files_related_morphs`

SET related_type =
CASE

WHEN related_type =‘terms’
THEN
‘api::term.term’ WHEN related_type =‘companies’
THEN
‘api::company.company’

WHEN related_type =‘contents’
THEN
‘content.content’ WHEN related_type =‘products’
THEN
‘api::product.product’

WHEN related_type =‘content_mores’
THEN
‘content.more’ WHEN related_type =‘users-permissions_user’
THEN
‘users::permissions_user’ ELSE related_type END;

SET FOREIGN_KEY_CHECKS=1;

Changes in server-side API

Changes in client API

The standard api response and request has new element data and meta so you will have to adjust your requests and response utilization accordingly also has count standard api removed against entities.

How we can help with the migration to strapi 4.

We are currently working on developing the automation script to aim 80 percent of automated migration script that will provide upgrade of schema files and other code files including routes. We are also developing scripts that will generate database migration scripts aiming MySQL, MariaDB and postgresql. If you have database in mongodb unfortunately we have not noticed if it is being supported in strapi 4. According to our team the mongodb may require migration via the api calls that downloads the data from strapi 2 and uploads into strapi 4 instance.

We will shortly publish these scripts online but in case you need access to their preview versions we can send these over on request. Please let us know if you need our professional services for migrations, we can offer a fast-paced response in term of strapi code upgrade, database migration, testing of migrations and upgrading your front ends developed with strapi.