Skip to content

Commit

Permalink
Add API v1 (#2595, #2425, #2331, #2066, #2062, #1762, #759, #394, #2530)
Browse files Browse the repository at this point in the history
This is a major rework of the API with a lot of breaking changes. See CHANGELOG_API.md for more information.

Note that we thought of disabling API generation in development (using JEKYLL_ENV like the Jekyll Feed plugin - see https://github.com/jekyll/jekyll-feed/blob/master/lib/jekyll-feed/generator.rb#L145), but it was finally reverted. It does not work well with Netlify preview, and generate production URL (i.e. https://endoflife.date URLs) in development which makes it difficult to use.
  • Loading branch information
marcwrobel committed Mar 9, 2024
1 parent 17ea0a7 commit 67af7fd
Show file tree
Hide file tree
Showing 16 changed files with 996 additions and 94 deletions.
96 changes: 96 additions & 0 deletions CHANGELOG_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
## API v1.0.0

### Summary

API v1 is a major rework of the API v0 with a lot of breaking changes. Compared to the API v0, API
v1:

- feels more _Restful_ (#2431),
- expose almost all product's data (#394, #759, #2062, #2595),
- expose new metadata such as `schema version` (#2331), `total` (for lists), `generated_at` or
`last modified` date,
- is easier to consume thanks to:
- new computed fields such as `is_maintained`,
- the replacement of fields that were using union types with two separate single-type fields:
- `lts` -> `isLts` and `ltsFrom`,
- `support` -> `isActiveSupportOver` and `activeSupportUntil`,
- `eol` -> `isEol` and `eolFrom`,
- `discontinued` -> `isDiscontinued` and `discontinuedFrom`,
- `extendedSupport` -> `isExtendedSupportOver` and `extendedSupportUntil`.
- provide new endpoints (#2078, #2160, #2530)
- is versioned using the `api/v1` prefix (#2066), making it easier to implement
non-backward-compatible changes in the future,
- is documented using [swagger-ui](https://swagger.io/tools/swagger-ui/) instead of [Stoplight
Elements WebComponent](https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/html.md)
(#905),
- but reverts #2425 due to incompatibilities in redirect rules.

The API v1 is now generated using a Jekyll Generator (see https://jekyllrb.com/docs/plugins/generators/)
instead of a custom script.

Note that the API v0 is still generated to give time to users to migrate to API v1. It will be
decommissioned at least one year after the API v1 release date.

API v1 documentation can be seen on <https://endoflife.date/docs/api/v1/>.
The old API v0 documentation can still be seen on <https://endoflife.date/docs/api/>.

### Changes in the "All products" endpoint

- Path has been changed from `api/all.json` to `api/v1/products/`
- Response has been changed from a simple array of strings to a JSON document.
This made it possible to include additional metadata, such as the schema version and the number of
products.
- Response items has been changed from a simple string (the product name) to a JSON document (#2062).
This made it possible to include additional information about the product, such as its category
and tags.
- See <https://endoflife.date/docs/api/v1/#/default/get_products> for a detailed description of the
response.

### Changes in the "Product" endpoint

- Path has been changed from `api/<product>.json` to `api/v1/products/<product>/`.
- Response has been changed from a simple array of versions to a JSON document.
This made it possible to include :
- additional metadata, such as the schema version and the last modified date,
- product-level information, such as the product label or category (#2062).
- Cycles data now always contain all the release cycles properties, even if they are null
(example: `discontinued`, `latest`, `latestReleaseDate`, `support`...).
- See <https://endoflife.date/docs/api/v1/#/default/get_products__product__> for a detailed
description of the response.

### Changes in the "Cycle" endpoint

- Path has been changed from `api/<product>/<cycle>.json` to `api/v1/products/<product>/cycles/<cycle>/`.
- Response has been changed to make it possible to include additional metadata, such as the schema
version and the last modified date,
- Cycles data now always contain all the release cycles properties, even if they are null
(example: `discontinued`, `latest`, `latestReleaseDate`, `support`...).
- A special `/api/v1/products/<product>/cycles/latest/` cycle, containing the same data as the
latest cycle, has been added (#2078).
- See <https://endoflife.date/docs/api/v1/#/default/get_products__product__cycles__cycle_> for a
detailed description of the response.

### Changes in 404 error responses

404 error JSON responses are not returned anymore. #2425 has been reverted because it conflicted
with the rule that rewrites the paths to add `/index.json` to all requests, which is also a global
rule and [takes precedence](https://docs.netlify.com/routing/redirects/#rule-processing-order).

### New endpoints

- `/api/v1/categories/`: Get a list of all categories.
- `/api/v1/categories/<category>`: Get a list of all products within the given category.
- `/api/v1/tags/`: Get a list of all tags.
- `/api/v1/tags/<tag>`: Get a list of all products having the given tag.
- `/api/v1/products/full/`: Get a list of all products with all their details (including cycles).
This endpoint provides a dump of nearly all the endoflife.date data.



## API v0

On 2023-03-02 the v0 endpoints were:

- "All products" (`/api/all.json`) : Get a list of all product names.
- "Product" (`/api/{product}.json`) : Get all release cycles details for a given product.
- "Cycle" (`/api/{product}/{cycle}.json`) : Get details for a single release cycle of a given product.
8 changes: 7 additions & 1 deletion HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,13 @@ The API is just JSON files generated in the `api` directory by `_plugins/create-

### API Documentation

The API Documentation is available at <https://endoflife.date/docs/api> and is generated from an OpenAPI Specification file located at `_data/openapi.yml`. The documentation is rendered [Stoplight Elements](https://meta.stoplight.io/docs/elements/ZG9jOjMyNjU4OTY0-introduction-to-elements).
The current API v1 documentation is available at <https://endoflife.date/docs/api/v1/> and is
generated from an OpenAPI Specification file located at `api_v1/openapi.yml`. The documentation is
rendered by [Swagger UI](https://swagger.io/tools/swagger-ui/).

The old API v0 documentation is available at <https://endoflife.date/docs/api> and is
generated from an OpenAPI Specification file located at `assets/openapi.yml`. The documentation is
rendered by [Stoplight Elements](https://meta.stoplight.io/docs/elements/ZG9jOjMyNjU4OTY0-introduction-to-elements).

## Contributing Workflow

Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ While participating in the project, you must abide by its [Code of Conduct](CODE

## API

An API is available for integration with CI platforms.
API documentation is available at https://endoflife.date/docs/api.
The API is currently in Alpha, and breaking changes can happen.
An API is available for integration with CI platforms. API documentation is available at https://endoflife.date/docs/api/v1/.
The API is currently in Beta, and breaking changes can happen.

## License

Expand All @@ -46,6 +45,8 @@ endoflife.date is relying on various amazing software and components :
- [Just the Docs](https://github.com/just-the-docs/just-the-docs), a documentation theme for Jekyll.
- [Stoplight Elements](https://stoplight.io/open-source/elements), a collection of UI components for
displaying beautiful developer documentation from any OpenAPI document.
- [Swagger UI](https://swagger.io/tools/swagger-ui/), a documentation generator for OpenAPI
Specification.
- [Simple Icons](https://simpleicons.org/), free SVG icons for popular brands.
- Our icon is derived from [Hourglass icon (orange)](https://commons.wikimedia.org/wiki/File:Hourglass_icon_%28orange%29.svg)
by David Abián and Serhio Magpie on the English Wikipedia. Remixed under the CC-BY-SA-4.0 license.
Expand Down
2 changes: 1 addition & 1 deletion _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ aux_links:
Source:
- https://github.com/endoflife-date/endoflife.date
API:
- /docs/api
- /docs/api/v1/
"Release Data":
- https://github.com/endoflife-date/release-data/

Expand Down
4 changes: 4 additions & 0 deletions _headers
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ layout: null
Content-Security-Policy: default-src 'none'; manifest-src 'self'; connect-src 'self'; script-src 'self'; style-src 'self'; img-src {{ defaultCspImgSrc }} {{ releaseImageSrc }}
Link: /api{{page.permalink}}.json; rel=alternate;type=application/json
Link: /calendar{{page.permalink}}.ics; rel=alternate;type=text/calendar
{% elsif page.permalink contains '/docs/api/v' %}
{%- comment %}Used contains to match all API version (startswith does not exist){% endcomment %}
# unsafe-inline and data: should not be an issue for a static site
Content-Security-Policy: default-src 'none'; manifest-src 'self'; connect-src 'self'; script-src 'self' 'unsafe-inline' https://unpkg.com/; style-src 'self' https://unpkg.com/; img-src 'self' data:
{% elsif page.permalink == '/docs/api' %}
Content-Security-Policy: default-src 'none'; manifest-src 'self'; connect-src 'self'; script-src 'self' https://unpkg.com/@stoplight/elements/web-components.min.js; style-src 'self' https://unpkg.com/@stoplight/elements/ 'unsafe-inline'
{% else %}
Expand Down
1 change: 1 addition & 0 deletions _layouts/json.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ page.data | jsonify }}
4 changes: 2 additions & 2 deletions _layouts/product.html
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ <h1>{{ page.title }}</h1>
</p>

<p>
A JSON version of this page is available at <a href="/api{{page.permalink}}.json">/api{{page.permalink}}.json</a>.
See the <a href="/docs/api/">API Documentation</a> for more information.
A JSON version of this page is available at <a href="/api/v1/products{{page.permalink}}/">/api/v1/products{{page.permalink}}/</a>.
See the <a href="/docs/api/v1/">API Documentation</a> for more information.
You can subscribe to the iCalendar feed at <a href="webcal://{{site.url | split: '://' | last}}/calendar{{page.permalink}}.ics">/calendar{{page.permalink}}.ics</a>.
</p>
31 changes: 31 additions & 0 deletions _layouts/swagger-ui.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
layout: null
---
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ page.title }}</title>

<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3/swagger-ui.css">
</head>

<body>
<div id="swagger-ui"></div>

<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
<script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js"></script>
<script>
window.onload = function () {
const ui = SwaggerUIBundle({
url: "{{ page.openapi_yml | absolute_url }}",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
plugins: [SwaggerUIBundle.plugins.DownloadUrl],
layout: "BaseLayout"
})
}
</script>
</body>
</html>
Loading

0 comments on commit 67af7fd

Please sign in to comment.