Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API Versioning #9866

Closed
kirrg001 opened this issue Sep 12, 2018 · 5 comments
Closed

API Versioning #9866

kirrg001 opened this issue Sep 12, 2018 · 5 comments
Assignees
Labels
affects:api Affects the Ghost API affects:server Issues relating to the server or core of Ghost feature [triage] New features we're planning or working on

Comments

@kirrg001
Copy link
Contributor

kirrg001 commented Sep 12, 2018

Why API Versioning?

  • We want to avoid that external clients break if they update their Ghost version. You either need to update the client first or your blog. You will always break clients for a period of time. With API versioning there’s no pressure to update immediately. You can even update to a new major version of Ghost without breaking your clients.
  • The public API is in beta since years now and we would like to work on a stable public API version.
  • The public and private API live on the same url (/api/v0.1/), but they both have different characteristics e.g. authentication, response values, restrictions. Having both on the same url makes it harder to maintain the code.
  • We would like to overhaul our current authentication strategies. Covered by API v2 - Authentication #9865.

Future of Ghost

In the near future we would like to achieve a 3 way split to make Ghost more customisable and flexible.

These are: Ghost Core, SDK’s and Clients.

Ghost Core

Should become API centric in the future, future. That means, our suite of APIs will be first class citizens allowing Ghost to function as a headless CMS.

SDK

Our suite of tools intended to help developers make use of APIs in their clients. SDKs should offer commonly used functionality that works on top of the data provided by an API in the form of small, reusable modules or components.

Clients

The ultimate API consumers. Some are interacted with by users, some by computers. They share common needs and so should be as small as possible, relying on shared code from the SDKs to solve common problems.

Reference Material / Research

Main Goals

  • Rename Public API to Content API and Private API to Admin API
  • API versioning for the Content and Admin API
  • First stable Content API
  • Admin API goes into Beta
  • Do not break v0.1 API
  • Support three API version at a time

API Versions

Based on the research material, we have decided to go with major versions only.
Examples for major versions: v1, v2, v3, v4 etc.

Reasons why we go with major versions:

  • Research material showed us that this is a very common approach.
  • We don’t want to force our clients to update their API version with any new feature/addition.

The Ghost active API version should equal the current major Ghost release. The latest Ghost major version is Ghost 2.x, that means we will introduce API version v2.

The latest/active API version should add concentrate on adding forwards compatible changes (add features, add routes, add new fields). As soon as we have to introduce breaking changes we have to:

  • add a new unstable (alpha/beta) API version
  • ensure we don’t break the old API versions

How does future versioning work?

The basic concept is (3 versions at a time):

  • current active version (feature additions)
  • stable version
  • deprecated version

Examples:

Ghost 2.0

  • v0.1
    • stable
  • v2
    • active version
    • breaking changes allowed initially, from there on only new functionality and forwards compatible
  • v3
    • we start with v3 as soon as we have breaking changes
    • we will release v3 before shipping Ghost 3.0
    • v3 becomes alpha/beta in Ghost 2.0
    • v3 becomes active in Ghost 3.0

Ghost 3.0

  • v0.1
    • deprecated, won’t break
  • v2
    • stable, won’t break
  • v3
    • active
    • new stuff allowed
    • breaking changes are not allowed
  • v4
    • we start with v4 as soon as have to introduce breaking changes, same as above

Endpoint design

Two new endpoints for v2 will be introduced:
We have decided to use url versioning, because it fits better to Ghost needs.

Reasons against API headers:

  • you can't put a header when accessing the url in the browser
  • it's harder to cache public/content api requests when using a header
  • if you don't provide an api header, you would fallback to the latest api version, which can create an unintended behaviour for clients
  • it's harder to add a header than putting the version into a url
  • we want to be explicit

The actual design

  • /api/v2/content/
    • public, read-only
    • v2 becomes active version
  • /api/v2/admin/
    • private, CRUD
    • goes into beta
  • /api/v0.1/
    • currently in beta
    • becomes “stable”
    • won’t break

Themes are clients

The theme has access to the API layer. It get’s data in and can pull more data from the API using the {{get}} helper. The theme layer is coupled with the actual blog site. They are both one client using the API. All themes currently use the API version v0.1.

We will introduce a new theme configuration option to define which API version you would like to use. This configuration value will probably live in the package.json of a theme. For now, if no api version is configured, we fallback to v0.1.

In the future it might be possible to define the version per helper, but that would be a future improvement.

Code Challenges

The biggest challenges are:

  • come up with a future proof folder structure to support api versioning
  • decouple model and api layer
  • decide which is shared functionality and which is not
  • granular API layers per API versions including serialisers
  • make it possible to reduce the maintenance cost for writing tests per API version
@kirrg001 kirrg001 added affects:server Issues relating to the server or core of Ghost affects:api Affects the Ghost API feature [triage] New features we're planning or working on labels Sep 12, 2018
@kirrg001 kirrg001 changed the title API versioning API Versioning Sep 12, 2018
kirrg001 pushed a commit that referenced this issue Sep 18, 2018
refs #9866

- Registered Content API under /ghost/api/v2/content/
- Registered Admin API under /ghost/api/v2/admin/
- Moved API v0.1 implementation to web/api/v0.1
- Created web/api/v2 for the new api endpoints
- Started with reducing the implementation for the new Content API (the Content api does not serve admin api endpoints, that's why it was reducible)
- Covered parent-app module with basic test checking correct applications/routes are being mounted
- Added a readme file, which contains a warning using v2, because it's under active development!
- This PR does only make the new endpoints available, we have not:
  - optimised the web folder (e.g. res.isAdmin)
  - started with different API controllers
  - reason: we want to do more preparation tasks before we copy the api controllers
kirrg001 pushed a commit that referenced this issue Sep 20, 2018
refs #9866

- Removed `res.isAdmin` flag in v2 express app
- Did not touch v0.1 express app
- Separated url redirect middleware for admin and content API
kirrg001 added a commit to kirrg001/Ghost that referenced this issue Sep 20, 2018
refs TryGhost#9866

- if we start with v2 controllers, the code base should not require specific api controllers
- because e.g. `require('../api/posts')` will no longer exist
- if you require the api folder, you will get the latest available version by default e.g. `require('../api').posts`
- this branch does not touch the test env (!)
kirrg001 pushed a commit that referenced this issue Sep 20, 2018
refs #9866

- Moved web/middleware to web/shared/middlewares
- Moved util file to web/shared/utils
kirrg001 added a commit to kirrg001/Ghost that referenced this issue Sep 20, 2018
refs TryGhost#9866

- the admin express app serves the client
- it only uses admin redirects
- we can use the new middleware function to avoid `res.isAdmin`
kirrg001 added a commit to kirrg001/Ghost that referenced this issue Sep 20, 2018
refs TryGhost#9866

- proof that the middleware works for many api versions
rishabhgrg pushed a commit that referenced this issue Sep 20, 2018
refs #9866

- the admin express app serves the client
- it only uses admin redirects
- we can use the new middleware function to avoid `res.isAdmin`
kirrg001 added a commit to kirrg001/Ghost that referenced this issue Sep 20, 2018
refs TryGhost#9866

- use package notation
- get rid of x requires for middlewares
- improved readability
- do not refactor web/api/v0.1
naz pushed a commit that referenced this issue Sep 20, 2018
Extended uncapitalise unit tests

refs #9866

- Proved that the middleware works for many API versions
- Added test case to prove that the version identifier gets lowercased too
@kirrg001
Copy link
Contributor Author

Closing. The work is done here. We've raised some more cleanup/optimisation issues for API V2.
See issue references above 👍

naz pushed a commit that referenced this issue Nov 2, 2018
refs #9866

- Added oembed controller to v2 API
naz added a commit to naz/Ghost that referenced this issue Dec 10, 2018
naz added a commit to naz/Ghost that referenced this issue Dec 17, 2018
naz added a commit to naz/Ghost that referenced this issue Dec 17, 2018
refs TryGhost#9866

- Migrated db import/export routes to use new db controller
naz added a commit that referenced this issue Dec 17, 2018
refs #9866

- Migrated db import/export routes to use new db controller
naz added a commit to naz/Ghost that referenced this issue Jan 4, 2019
refs TryGhost#9866

- Migrated redirect routes to use new redirect controller
naz added a commit that referenced this issue Jan 7, 2019
refs #9866

- Migrated redirect routes to use new redirect controller
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects:api Affects the Ghost API affects:server Issues relating to the server or core of Ghost feature [triage] New features we're planning or working on
Projects
None yet
Development

No branches or pull requests

4 participants