Prototypr is a publishing platform using Strapi for the CMS, and the site has an editor for users to draft and submit articles. This process relies on document versioning, and that didn't come with Strapi 4. Now versioning is available in Strapi 5 out the box, this post shows you how the new Document Versioning works under the hood.
To start with though, here' show I was doing document versioning in Strapi 4 - you'll see how Strapi 5 has hugely improved the workflow for publishing teams:
Before Document Versioning:
Since Strapi 4 doesn't have document versioning, I had to make my own with a draft/edit system which relied on a 'status' field on each post record for 'draft', 'publish', or 'pending'.
Each post record also held both the draft and the published versions using fields called draft_content and draft_title. Upon hitting publish, the draft_content would replace the main content field on that post.
This process was enabled through a front-end editor that handled the post status, called Typr:

Letter
Enter Strapi 5 Version Control
While my version control editor worked, it could get confusing. Each post record held both the draft content and the live content. The publish status was also just a string. Also, the Strapi admin dashboard didn't show the draft or published state. Strapi 5 introduces a great system to do this now:
With Draft & Publish, managing content is now more intuitive. You can handle content at every stage of its lifecycle, whether it's a draft, ready for publishing, or marked for modification. This feature reduces the risk of publishing errors and makes it easier for teams to collaborate.
Draft: The content has never been published and is still a work in progress.
Modified: The content has been published before, but recent changes have been saved as a draft. These changes aren’t live yet, offering you a chance to refine them before the next publication.
Published: The content is live and visible to your audience. No pending draft changes are saved.
How Draft/Publishing system works with Document_id
Strapi 5 makes versioning a lot better than was previously possible. It's now built right into Strapi, which makes things a lot simpler. In contrast to storing draft content and published content in 1 entry, Strapi introduced a new document_id field that makes versioning possible at the database level.
To demonstrate, we can look at how this works in the SQL database. If I order the posts in a Strapi 5 database by name, you can see there's now 2 database entries for each individual - a draft and published version:

SELECT title, date, published_at, document_id FROM posts ORDER BY title desc
Versions are linked by document_id
This approach allows the user to continue editing the draft, and then submit for review. You can also see how the new document_id column in Strapi 5 works by linking together database rows related to the same post (draft/pubished).
I'm guessing when you hit publish changes on a draft, the published_at field is moved to the version you hit pubish on, leaving the old version with published_at as null, now making it the 'working draft' version. In contrast here's how a Strapi 4 database looked:

In Strapi 4, each entry appears once in the database, and you rely on the actual ID as the document identifier. To reiterate, the document_id was introduced in Strapi 5 to group posts. That's why in Strapi 5, they've introduced the new Document Service API.
Why migrate to a new Document Service API?
The Document Service API queries based on document_id instead of the actual postgres ID field. That enables it to work with the draft/publish system. It's also why we need to migrate from the Entity Service API that we used to use:

If you continue using the Entity Service API, if you query by post title, it's going to return multiple posts, whereas the Document Service API will return 1.
Enable/Disable Document Versioning (Under the hood)
If you don't need a draft/publish system, and were happy with Strapi 4, you can turn off the document versioning. If you click Edit on your content type, then go to the 'Advanced Settings' tab, you can uncheck Draft & publish:

That will change your database to be more like Strapi 4, where each post will exist in the database on its own. It will still have the new document_id field, but there are no other versions sharing that document_id.
Here you can see the before and after for version control enabled/disabled in Strapi 5:
Version Control Enabled:
![Version control enabled: 2 posts per document_id. [null] published_at field on draft versions, and date present on published version](https://prototypr-media-backup.nyc3.digitaloceanspaces.com/strapi/e87a49f0f02adacb9171cf6f2e88ef8b.png)
Version Control Disabled:

So now if you query using the old Entity Service, it would only show you one post again, as versioning is not active.
Strapi 5 is great for publishers
I think some people had found the new APIs and changes confusing at first:
Why do we need a new Document Service API?
Why are my queries returning duplicate posts?
Issues often resulted from using the deprecated Entity Service API with the Strapi 5's document versioning active. It was the same for me, and the upgrade to Strapi 5 meant significant changes to the Prototypr site and editor.
Overall, updating from Strapi 4 to Strapi 5 was a big change, but overall it significantly improves Prototypr editing flow, and I can focus on improving the site instead of getting stuck with publishing bugs.
Plus the new Publishing/Draft overview sections on the Strapi admin dashboard are handy:

I hope this post clears up why those issues were happening, and also why the changes are really helpful for publishers.
If you have any questions let me know. The new comment system on this site is invite only (I know, not so helpful for technical questions), so get in touch for an invite at hello[at]prototypr[dot]io for an invite, or comments.