# Squidex 3.0: API Compatibility

The API for Squidex 3.0 contains a lot of changes to 2.0. This document describes the main differences.

The good news first! There is no change in the endpoints to retrieve content or assets, including the GraphQL endpoint.

## Motivation

These changes are driven by two requirements:

1. `POST` and `PUT` endpoints must return the full entity (e.g. the schema object) so that the UI does not have to consider how the entity will be structured after an update.
2. Implement `HATEOAS` (Hypermedia as the Engine of Application State) to tell the client which operations are possible for a given entity and how to invoke them.

Given the list of Apps as an example, our JSON response has the following format now:

```javascript
{
   "items": [{
       "id": 1,
       "name": "my-app",
       "_links": {
          "delete": { "method": "DELETE", "href": "/api/apps/1" }
       }
    }],
    "_links": {
        "create": { "method": "POST", "href": "/api/apps" }
     }
}
```

This format will be called **Items-Object** from now.

A single App in 3.0 has the following format:

```javascript
{
    "id": 1,
    "name": "my-app",
    "_links": {
        "delete": { "method": "DELETE", "href": "/api/apps/1" }
    }
}
```

If Squidex 2.0 and a lower list of Apps was returned as a JSON array, it will not be  possible to add the links to create the endpoint.

```javascript
[{
    "id": 1,
    "name": "my-app",
    "_links": {
        "delete": { "method": "DELETE", "href": "/api/apps/1" }
    }
}]
```

## General Changes

### 1. HATEOAS

As described above, each entity or list of entities will now contain a `_links` object, with all possible operations. If the operation is not possible or the current user does not have the correct permission, the link will not be present.

> RISK to break something: **LOW**

### 2. Metadata

Data that is not part of the entity but must be returned as a result of the operation is added to a `_meta` object.

Example: When uploading an asset, the API checks if the same asset has already been uploaded. If this is the case, the response will contain the uploaded asset with additional information if the asset was already part of the App:

```javascript
{
    "id": 1,
    "fileName": "Logo.jpeg",
    "fileSize": 1024,
    "_links": {
        "delete": { "method": "DELETE", "href": "/api/assets/1" }
    },
    "_meta": {
        "isDuplicate": "1"
    }
}
```

> RISK to break something: **LOW**

### 3. Full Response Objects

All `POST` and `PUT` endpoints now return the full entity (e.g. the schema object). This is not a breaking change for you if your client displays the following behaviour:

1. The client does not break when the JSON response contains additional properties.
2. The client does not break when an endpoint that has previously returned a `204 No Content` status code now returns `200 OK` now (usually the case).
3. The client does not break when an endpoint that has not returned a JSON response before, now returns a response.

> RISK to break something: **MEDIUM**

## Specific Changes

### Contents

The following endpoints have been removed to prepare for the coming workflow system:

* `PUT /api/content/{app}/{name}/{id}/archive/`
* `PUT /api/content/{app}/{name}/{id}/publish/`
* `PUT /api/content/{app}/{name}/{id}/restore/`
* `PUT /api/content/{app}/{name}/{id}/unpublish/`

The replacement is a generalized status endpoint:

```javascript
PUT /api/content/{app}/{name}/{id}/status/

{
    "status": "Published"
}
```

> RISK to break something: **HIGH**

### Assets

1. `POST /api/apps/{app}/assets/` does not return the `isDuplicate` JSON property anymore, it has been replaced with metadata (see example above).

> RISK to break something: **LOW**

### Rules

1. `GET /api/apps/{app}/rules/` endpoint returns **Items-Object** instead of a JSON array.

> RISK to break something: **LOW**

### Apps

1. `GET /api/apps/` endpoint returns **Items-Object** instead of JSON array.
2. `GET /api/apps/{app}/clients/` endpoint returns **Items-Object** instead of JSON array.
3. `GET /api/apps/{app}/languages/` endpoint returns **Items-Object** instead of JSON array.
4. `GET /api/apps/{app}/contributors/` endpoint returns **Items-Object** instead of custom JSON object.
5. `GET /api/apps/{app}/patterns/` endpoint returns **Items-Object** instead of JSON array.
6. `GET /api/apps/{app}/roles/` endpoint returns **Items-Object** instead of custom JSON object.

> RISK to break something: **LOW**
