Table of Contents

Simple operations

MibServer API provides the CRUD (Create-Read-Update-Delete) operations common to all media types according to the user permissions. Later in this document will be detailed how to group one or more of these operations in a single HTTP request, but the concept will be the same.


1 - Read a single entity

GET /api/v1/mvp_genres_metadatas/3?hidemeta=1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
If-None-Match: "r0Wv3r$10n0"
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
ETag: "r0Wv3r$10n1"
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "_links": {
    "mvp_genres_metadatas.owner": {
      "_href": "/api/v1/adm_users/{mvp_genres_metadatas.owner}",
      "_type": "adm_users"
    }
  },
  "mvp_genres_metadatas": [
    {
      "_id": 3,
      "_href": "/api/v1/mvp_genres_metadatas/1",
      "_type": "mvp_genres_metadatas",
      "_etag": "DVEQCwwSxwgByrJsxSLdXQ",
      "dateins": 1474574159,
      "name": "Action",
      "genre_id": 1,
      "language_id": 1,
      "title": "Action",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    }
  ],
  "_linked": {}
}

Attention: as of MIB v5.0.x, if this method is called with an invalid id, the API still responds with status code 200, and an empty entity. This is being kept this way for backwards compatibility reasons with the rest of the MIB CMS components, and will be revised in the future. Temporarilly, to allow other APIs to get the correct response, a flag was introduced. You can read about it (and how to use) here.


2 - Read an entity list

All list operations will be paged and return metadata information such as total row count for the filter, next page and previous page links when available. When no page is specified, API will consider as being the first page.

GET /api/v1/mvp_genres_metadatas?pagesize=5 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "_meta": {
    "_pageCount": 2,
    "_filterRowCount": 6,
    "_pageSize": 5,
    "_previousPage": "",
    "_nextPage": "/api/v1/MVP_GENRES_METADATAS?pagesize=5&page=1",
    "_mainMediaType": "mvp_genres_metadatas",
    "_ids": null,
    "_childMediaType": null,
    "_include": [],
    "_sortOrder": {},
    "_fields": {},
    "_filter": {
      "_root": {
        "operator": "and",
        "children": []
      }
    },
    "_page": 0,
    "_hideMeta": false,
    "_hideLinks": false,
    "contentSelection": null
  },
  "_links": {
    "mvp_genres_metadatas.owner": {
      "_href": "/api/v1/adm_users/{mvp_genres_metadatas.owner}",
      "_type": "adm_users"
    }
  },
  "mvp_genres_metadatas": [
    {
      "_id": 1,
      "_href": "/api/v1/mvp_genres_metadatas/1",
      "_type": "mvp_genres_metadatas",
      "_etag": "DVEQCwwSxwgByrJsxSLdXQ",
      "dateins": 1474574159,
      "name": "Action",
      "genre_id": 1,
      "language_id": 1,
      "title": "Action",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 2,
      "_href": "/api/v1/mvp_genres_metadatas/2",
      "_type": "mvp_genres_metadatas",
      "_etag": "8T6t23JrbPMWIRZHWu2dTg",
      "dateins": 1474574305,
      "name": "Adventure",
      "genre_id": 3,
      "language_id": 1,
      "title": "Adventure",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 6,
      "_href": "/api/v1/mvp_genres_metadatas/6",
      "_type": "mvp_genres_metadatas",
      "_etag": "OhoQJuDRZ0JnlJlaCyYc2A",
      "dateins": 1474574430,
      "name": "Animation",
      "genre_id": 9,
      "language_id": 1,
      "title": "Animation",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 4,
      "_href": "/api/v1/mvp_genres_metadatas/4",
      "_type": "mvp_genres_metadatas",
      "_etag": "MwjV70IdngdRbjhW0vVNRA",
      "dateins": 1474574354,
      "name": "Comedy",
      "genre_id": 10,
      "language_id": 1,
      "title": "Comedy",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 3,
      "_href": "/api/v1/mvp_genres_metadatas/3",
      "_type": "mvp_genres_metadatas",
      "_etag": "ys5Ix0xAiRXl66elOVpq6A",
      "dateins": 1474574327,
      "name": "Drama",
      "genre_id": 5,
      "language_id": 1,
      "title": "Drama",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    }
  ],
  "_linked": {},
  "_permissions": {
    "can_create": true
  }
}

3 - Read a referenced sublevel entity or list

If you want to find all related objects of a media type, without querying the media type itself, you can use a sublevel action. Only one level is allowed this time. To search for the comedy (id 1) movies you should use the following header:

GET /api/v1/mvp_genres_metadatas/3/mvp_movies HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

All kinds of relationship are allowed: one-to-many, many-to-one, one-to-one, many-to-many and LinkObjects, once the ADM_RELATEDS table is correctly filled. If the right media type of your query is the "many" part of a "to-many" relationship, the result will be a collection, otherwise will be a single entity. As a genre contains one or many movies, the result of above example will return a collection (paged, always). If you type mvp_movies/1/mvp_producers and considering that this is a many-to-one relationship (a movie has only one producer), then this query will result in a single entity response.


4 - Read a collection by list of ids (select in)

Sometimes you have a list of ids and want to obtain the respectives objects. You can split the ids with comma as shown below:

GET /api/v1/mvp_genres_metadatas/1,4,6,23,53 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

If no sort order is specified in a query configuration parameter the collection will be sorted by ascending name.


5 - Additional query configuration parameters

The API exposes several query parameters that allows you to configure your search or the returning object.


5.1 - Include sublevels (preload)

Parameter "include" is a comma-separated list of related media types that will be preloaded and sent in JSON response which is then called "compound document". Second level can be reached using dot-notation, but remember to reference first level before, e.g., /api/v1/customer/1?include=orders,orders.products,orders.address will load the customer with Id equals to 1, all the orders made by this customer, the products included in each order, and delivery address of each order. ORDERS, PRODUCTS and ADDRESS are the media type names (tables), not the relationship properties. As Mib currently doesn't support two relationships between the same media types, there's no ambiguity. All included items are detailed after main item (or main collection when result is a list) and under the root member "linked", but relationship is represented in master object as a dictionary of media types and list of ids under the member "links".

GET /api/v1/mvp_genres_metadatas/3?include=adm_users,mvp_movies,mvp_movies.mvp_producers&hidemeta=1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
If-None-Match: "r0Wv3r$10n0"
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
ETag: "r0Wv3r$10n1"
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "_links":{
      "mvp_genres_metadatas.owner":{
         "_href":"/api/v1/adm_users/{mvp_genres_metadatas.owner}",
         "_type":"adm_users"
      },
      "mvp_genres_metadatas.mvp_movies":{
         "_href":"/api/v1/mvp_genres_metadatas/{mvp_genres_metadatas.id}/mvp_movies",
         "_type":"mvp_movies"
      },
      "adm_users.owner":{
         "_href":"/api/v1/adm_users/{adm_users.owner}",
         "_type":"adm_users"
      },
      "adm_users.businessrules[owner]":{
         "_href":"/api/v1/businessrules?owner={adm_users.id}",
         "_type":"businessrules"
      },
      "adm_users.cdn_bpoints[owner]":{
         "_href":"/api/v1/cdn_bpoints?owner={adm_users.id}",
         "_type":"cdn_bpoints"
      },
      "adm_users.agents_ipwhitelist[owner]":{
         "_href":"/api/v1/agents_ipwhitelist?owner={adm_users.id}",
         "_type":"agents_ipwhitelist"
      },
      "adm_users.cdn_ipranges[owner]":{
         "_href":"/api/v1/cdn_ipranges?owner={adm_users.id}",
         "_type":"cdn_ipranges"
      },
      "adm_users.cdn_lives[owner]":{
         "_href":"/api/v1/cdn_lives?owner={adm_users.id}",
         "_type":"cdn_lives"
      },
      "adm_users.cdn_mirrors[owner]":{
         "_href":"/api/v1/cdn_mirrors?owner={adm_users.id}",
         "_type":"cdn_mirrors"
      },
      "adm_users.cdn_regions[owner]":{
         "_href":"/api/v1/cdn_regions?owner={adm_users.id}",
         "_type":"cdn_regions"
      },
      "adm_users.channels[owner]":{
         "_href":"/api/v1/channels?owner={adm_users.id}",
         "_type":"channels"
      },
      "adm_users.contents[owner]":{
         "_href":"/api/v1/contents?owner={adm_users.id}",
         "_type":"contents"
      },
      "adm_users.flashes[owner]":{
         "_href":"/api/v1/flashes?owner={adm_users.id}",
         "_type":"flashes"
      },
      "adm_users.flashes_multiplefiles[owner]":{
         "_href":"/api/v1/flashes_multiplefiles?owner={adm_users.id}",
         "_type":"flashes_multiplefiles"
      },
      "adm_users.geocountries[owner]":{
         "_href":"/api/v1/geocountries?owner={adm_users.id}",
         "_type":"geocountries"
      },
      "adm_users.geocoveringmirror[owner]":{
         "_href":"/api/v1/geocoveringmirror?owner={adm_users.id}",
         "_type":"geocoveringmirror"
      },
      "adm_users.georegions[owner]":{
         "_href":"/api/v1/georegions?owner={adm_users.id}",
         "_type":"georegions"
      },
      "adm_users.images[owner]":{
         "_href":"/api/v1/images?owner={adm_users.id}",
         "_type":"images"
      },
      "adm_users.images_multiplefiles[owner]":{
         "_href":"/api/v1/images_multiplefiles?owner={adm_users.id}",
         "_type":"images_multiplefiles"
      },
      "adm_users.links[owner]":{
         "_href":"/api/v1/links?owner={adm_users.id}",
         "_type":"links"
      },
      "adm_users.media_types[owner]":{
         "_href":"/api/v1/media_types?owner={adm_users.id}",
         "_type":"media_types"
      },
      "adm_users.mmedias[owner]":{
         "_href":"/api/v1/mmedias?owner={adm_users.id}",
         "_type":"mmedias"
      },
      "adm_users.mmedias_multiplefiles[owner]":{
         "_href":"/api/v1/mmedias_multiplefiles?owner={adm_users.id}",
         "_type":"mmedias_multiplefiles"
      },
      "adm_users.sources[owner]":{
         "_href":"/api/v1/sources?owner={adm_users.id}",
         "_type":"sources"
      },
      "adm_users.str_extensions[owner]":{
         "_href":"/api/v1/str_extensions?owner={adm_users.id}",
         "_type":"str_extensions"
      },
      "adm_users.str_profiles[owner]":{
         "_href":"/api/v1/str_profiles?owner={adm_users.id}",
         "_type":"str_profiles"
      },
      "adm_users.str_profiles_multiplefiles[owner]":{
         "_href":"/api/v1/str_profiles_multiplefiles?owner={adm_users.id}",
         "_type":"str_profiles_multiplefiles"
      },
      "adm_users.str_servertypes[owner]":{
         "_href":"/api/v1/str_servertypes?owner={adm_users.id}",
         "_type":"str_servertypes"
      },
      "adm_users.templates[owner]":{
         "_href":"/api/v1/templates?owner={adm_users.id}",
         "_type":"templates"
      },
      "adm_users.templates_pos[owner]":{
         "_href":"/api/v1/templates_pos?owner={adm_users.id}",
         "_type":"templates_pos"
      },
      "adm_users.texts[owner]":{
         "_href":"/api/v1/texts?owner={adm_users.id}",
         "_type":"texts"
      },
      "adm_users.times[owner]":{
         "_href":"/api/v1/times?owner={adm_users.id}",
         "_type":"times"
      },
      "adm_users.uploadtimes[owner]":{
         "_href":"/api/v1/uploadtimes?owner={adm_users.id}",
         "_type":"uploadtimes"
      },
      "adm_users.dmm_local_folders[owner]":{
         "_href":"/api/v1/dmm_local_folders?owner={adm_users.id}",
         "_type":"dmm_local_folders"
      },
      "adm_users.dmm_remote_folders[owner]":{
         "_href":"/api/v1/dmm_remote_folders?owner={adm_users.id}",
         "_type":"dmm_remote_folders"
      },
      "adm_users.dmm_jobs[owner]":{
         "_href":"/api/v1/dmm_jobs?owner={adm_users.id}",
         "_type":"dmm_jobs"
      },
      "adm_users.dmm_jobs_actions[owner]":{
         "_href":"/api/v1/dmm_jobs_actions?owner={adm_users.id}",
         "_type":"dmm_jobs_actions"
      },
      "adm_users.dmm_subscriptions[owner]":{
         "_href":"/api/v1/dmm_subscriptions?owner={adm_users.id}",
         "_type":"dmm_subscriptions"
      },
      "adm_users.dmm_image_profiles[owner]":{
         "_href":"/api/v1/dmm_image_profiles?owner={adm_users.id}",
         "_type":"dmm_image_profiles"
      },
      "adm_users.dmm_downloaders[owner]":{
         "_href":"/api/v1/dmm_downloaders?owner={adm_users.id}",
         "_type":"dmm_downloaders"
      },
      "adm_users.dmm_encoders[owner]":{
         "_href":"/api/v1/dmm_encoders?owner={adm_users.id}",
         "_type":"dmm_encoders"
      },
      "adm_users.dmm_uploaders[owner]":{
         "_href":"/api/v1/dmm_uploaders?owner={adm_users.id}",
         "_type":"dmm_uploaders"
      },
      "adm_users.dmm_cleaners[owner]":{
         "_href":"/api/v1/dmm_cleaners?owner={adm_users.id}",
         "_type":"dmm_cleaners"
      },
      "adm_users.dmm_thumbnail_agents[owner]":{
         "_href":"/api/v1/dmm_thumbnail_agents?owner={adm_users.id}",
         "_type":"dmm_thumbnail_agents"
      },
      "adm_users.dmm_subscriptions_agents[owner]":{
         "_href":"/api/v1/dmm_subscriptions_agents?owner={adm_users.id}",
         "_type":"dmm_subscriptions_agents"
      },
      "adm_users.dmm_aspect_ratio[owner]":{
         "_href":"/api/v1/dmm_aspect_ratio?owner={adm_users.id}",
         "_type":"dmm_aspect_ratio"
      },
      "adm_users.dmm_resizers[owner]":{
         "_href":"/api/v1/dmm_resizers?owner={adm_users.id}",
         "_type":"dmm_resizers"
      },
      "adm_users.dmm_errors[owner]":{
         "_href":"/api/v1/dmm_errors?owner={adm_users.id}",
         "_type":"dmm_errors"
      },
      "adm_users.adm_addins[owner]":{
         "_href":"/api/v1/adm_addins?owner={adm_users.id}",
         "_type":"adm_addins"
      },
      "adm_users.adm_audit[owner]":{
         "_href":"/api/v1/adm_audit?owner={adm_users.id}",
         "_type":"adm_audit"
      },
      "adm_users.adm_enumtypes[owner]":{
         "_href":"/api/v1/adm_enumtypes?owner={adm_users.id}",
         "_type":"adm_enumtypes"
      },
      "adm_users.adm_enumvalues[owner]":{
         "_href":"/api/v1/adm_enumvalues?owner={adm_users.id}",
         "_type":"adm_enumvalues"
      },
      "adm_users.adm_fields[owner]":{
         "_href":"/api/v1/adm_fields?owner={adm_users.id}",
         "_type":"adm_fields"
      },
      "adm_users.adm_fileextensions[owner]":{
         "_href":"/api/v1/adm_fileextensions?owner={adm_users.id}",
         "_type":"adm_fileextensions"
      },
      "adm_users.adm_groups[owner]":{
         "_href":"/api/v1/adm_groups?owner={adm_users.id}",
         "_type":"adm_groups"
      },
      "adm_users.adm_menu[owner]":{
         "_href":"/api/v1/adm_menu?owner={adm_users.id}",
         "_type":"adm_menu"
      },
      "adm_users.adm_relateds[owner]":{
         "_href":"/api/v1/adm_relateds?owner={adm_users.id}",
         "_type":"adm_relateds"
      },
      "adm_users.adm_rights[owner]":{
         "_href":"/api/v1/adm_rights?owner={adm_users.id}",
         "_type":"adm_rights"
      },
      "adm_users.adm_sites[owner]":{
         "_href":"/api/v1/adm_sites?owner={adm_users.id}",
         "_type":"adm_sites"
      },
      "adm_users.pages[owner]":{
         "_href":"/api/v1/pages?owner={adm_users.id}",
         "_type":"pages"
      },
      "adm_users.adm_users[owner]":{
         "_href":"/api/v1/adm_users?owner={adm_users.id}",
         "_type":"adm_users"
      },
      "adm_users.adm_preferences[owner]":{
         "_href":"/api/v1/adm_preferences?owner={adm_users.id}",
         "_type":"adm_preferences"
      },
      "adm_users.adm_quickpublish[owner]":{
         "_href":"/api/v1/adm_quickpublish?owner={adm_users.id}",
         "_type":"adm_quickpublish"
      },
      "adm_users.adm_quickpublish_actions[owner]":{
         "_href":"/api/v1/adm_quickpublish_actions?owner={adm_users.id}",
         "_type":"adm_quickpublish_actions"
      },
      "adm_users.adm_quickpublish_requirements[owner]":{
         "_href":"/api/v1/adm_quickpublish_requirements?owner={adm_users.id}",
         "_type":"adm_quickpublish_requirements"
      },
      "adm_users.adm_quickcontent[owner]":{
         "_href":"/api/v1/adm_quickcontent?owner={adm_users.id}",
         "_type":"adm_quickcontent"
      },
      "adm_users.adm_quickcontent_blocks[owner]":{
         "_href":"/api/v1/adm_quickcontent_blocks?owner={adm_users.id}",
         "_type":"adm_quickcontent_blocks"
      },
      "adm_users.content_marks[owner]":{
         "_href":"/api/v1/content_marks?owner={adm_users.id}",
         "_type":"content_marks"
      },
      "adm_users.adm_quicklist[owner]":{
         "_href":"/api/v1/adm_quicklist?owner={adm_users.id}",
         "_type":"adm_quicklist"
      },
      "adm_users.adm_quicklist_actions[owner]":{
         "_href":"/api/v1/adm_quicklist_actions?owner={adm_users.id}",
         "_type":"adm_quicklist_actions"
      },
      "adm_users.languages[owner]":{
         "_href":"/api/v1/languages?owner={adm_users.id}",
         "_type":"languages"
      },
      "adm_users.translations_applications[owner]":{
         "_href":"/api/v1/translations_applications?owner={adm_users.id}",
         "_type":"translations_applications"
      },
      "adm_users.translations_sections[owner]":{
         "_href":"/api/v1/translations_sections?owner={adm_users.id}",
         "_type":"translations_sections"
      },
      "adm_users.translations_keys[owner]":{
         "_href":"/api/v1/translations_keys?owner={adm_users.id}",
         "_type":"translations_keys"
      },
      "adm_users.translations_items[owner]":{
         "_href":"/api/v1/translations_items?owner={adm_users.id}",
         "_type":"translations_items"
      },
      "adm_users.translations_values[owner]":{
         "_href":"/api/v1/translations_values?owner={adm_users.id}",
         "_type":"translations_values"
      },
      "adm_users.translations_images[owner]":{
         "_href":"/api/v1/translations_images?owner={adm_users.id}",
         "_type":"translations_images"
      },
      "adm_users.dmm_drms[owner]":{
         "_href":"/api/v1/dmm_drms?owner={adm_users.id}",
         "_type":"dmm_drms"
      },
      "adm_users.dmm_post_processors[owner]":{
         "_href":"/api/v1/dmm_post_processors?owner={adm_users.id}",
         "_type":"dmm_post_processors"
      },
      "adm_users.cdn_farms[owner]":{
         "_href":"/api/v1/cdn_farms?owner={adm_users.id}",
         "_type":"cdn_farms"
      },
      "adm_users.cdn_mirror_storages[owner]":{
         "_href":"/api/v1/cdn_mirror_storages?owner={adm_users.id}",
         "_type":"cdn_mirror_storages"
      },
      "adm_users.geocoveringfarm[owner]":{
         "_href":"/api/v1/geocoveringfarm?owner={adm_users.id}",
         "_type":"geocoveringfarm"
      },
      "adm_users.cdn_mirror_storage_urls[owner]":{
         "_href":"/api/v1/cdn_mirror_storage_urls?owner={adm_users.id}",
         "_type":"cdn_mirror_storage_urls"
      },
      "adm_users.dmm_importer_scheduler[owner]":{
         "_href":"/api/v1/dmm_importer_scheduler?owner={adm_users.id}",
         "_type":"dmm_importer_scheduler"
      },
      "adm_users.dmm_importers[owner]":{
         "_href":"/api/v1/dmm_importers?owner={adm_users.id}",
         "_type":"dmm_importers"
      },
      "adm_users.mvp_content_categories[owner]":{
         "_href":"/api/v1/mvp_content_categories?owner={adm_users.id}",
         "_type":"mvp_content_categories"
      },
      "adm_users.mvp_distributors[owner]":{
         "_href":"/api/v1/mvp_distributors?owner={adm_users.id}",
         "_type":"mvp_distributors"
      },
      "adm_users.mvp_genres[owner]":{
         "_href":"/api/v1/mvp_genres?owner={adm_users.id}",
         "_type":"mvp_genres"
      },
      "adm_users.mvp_genres_metadatas[owner]":{
         "_href":"/api/v1/mvp_genres_metadatas?owner={adm_users.id}",
         "_type":"mvp_genres_metadatas"
      },
      "adm_users.mvp_importer_errors[owner]":{
         "_href":"/api/v1/mvp_importer_errors?owner={adm_users.id}",
         "_type":"mvp_importer_errors"
      },
      "adm_users.mvp_instances[owner]":{
         "_href":"/api/v1/mvp_instances?owner={adm_users.id}",
         "_type":"mvp_instances"
      },
      "adm_users.mvp_instances_age_ratings[owner]":{
         "_href":"/api/v1/mvp_instances_age_ratings?owner={adm_users.id}",
         "_type":"mvp_instances_age_ratings"
      },
      "adm_users.mvp_movies[owner]":{
         "_href":"/api/v1/mvp_movies?owner={adm_users.id}",
         "_type":"mvp_movies"
      },
      "adm_users.mvp_movies_age_ratings[owner]":{
         "_href":"/api/v1/mvp_movies_age_ratings?owner={adm_users.id}",
         "_type":"mvp_movies_age_ratings"
      },
      "adm_users.mvp_movies_metadatas[owner]":{
         "_href":"/api/v1/mvp_movies_metadatas?owner={adm_users.id}",
         "_type":"mvp_movies_metadatas"
      },
      "adm_users.mvp_persons[owner]":{
         "_href":"/api/v1/mvp_persons?owner={adm_users.id}",
         "_type":"mvp_persons"
      },
      "adm_users.mvp_persons_roles[owner]":{
         "_href":"/api/v1/mvp_persons_roles?owner={adm_users.id}",
         "_type":"mvp_persons_roles"
      },
      "adm_users.mvp_producers[owner]":{
         "_href":"/api/v1/mvp_producers?owner={adm_users.id}",
         "_type":"mvp_producers"
      },
      "adm_users.mvp_subtitles[owner]":{
         "_href":"/api/v1/mvp_subtitles?owner={adm_users.id}",
         "_type":"mvp_subtitles"
      },
      "adm_users.mvp_xmls[owner]":{
         "_href":"/api/v1/mvp_xmls?owner={adm_users.id}",
         "_type":"mvp_xmls"
      },
      "adm_users.mvp_xmls_multiplefiles[owner]":{
         "_href":"/api/v1/mvp_xmls_multiplefiles?owner={adm_users.id}",
         "_type":"mvp_xmls_multiplefiles"
      },
      "adm_users.dmm_fragmenters[owner]":{
         "_href":"/api/v1/dmm_fragmenters?owner={adm_users.id}",
         "_type":"dmm_fragmenters"
      },
      "adm_users.dmm_post_cleaners[owner]":{
         "_href":"/api/v1/dmm_post_cleaners?owner={adm_users.id}",
         "_type":"dmm_post_cleaners"
      },
      "adm_users.content_criteria[owner]":{
         "_href":"/api/v1/content_criteria?owner={adm_users.id}",
         "_type":"content_criteria"
      },
      "adm_users.content_criteria_filters[owner]":{
         "_href":"/api/v1/content_criteria_filters?owner={adm_users.id}",
         "_type":"content_criteria_filters"
      },
      "adm_users.api_clients[owner]":{
         "_href":"/api/v1/api_clients?owner={adm_users.id}",
         "_type":"api_clients"
      },
      "adm_users.api_client_users[owner]":{
         "_href":"/api/v1/api_client_users?owner={adm_users.id}",
         "_type":"api_client_users"
      },
      "adm_users.api_client_users[user_id]":{
         "_href":"/api/v1/api_client_users?user_id={adm_users.id}",
         "_type":"api_client_users"
      },
      "adm_users.api_refreshtokens[owner]":{
         "_href":"/api/v1/api_refreshtokens?owner={adm_users.id}",
         "_type":"api_refreshtokens"
      },
      "adm_users.adm_groups":{
         "_href":"/api/v1/adm_users/{adm_users.id}/adm_groups",
         "_type":"adm_groups"
      },
      "mvp_movies.owner":{
         "_href":"/api/v1/adm_users/{mvp_movies.owner}",
         "_type":"adm_users"
      },
      "mvp_movies.producer_id":{
         "_href":"/api/v1/mvp_producers/{mvp_movies.producer_id}",
         "_type":"mvp_producers"
      },
      "mvp_movies.mvp_genres_metadatas":{
         "_href":"/api/v1/mvp_movies/{mvp_movies.id}/mvp_genres_metadatas",
         "_type":"mvp_genres_metadatas"
      },
      "mvp_movies.channels":{
         "_href":"/api/v1/mvp_movies/{mvp_movies.id}/channels",
         "_type":"channels"
      },
      "mvp_producers.owner":{
         "_href":"/api/v1/adm_users/{mvp_producers.owner}",
         "_type":"adm_users"
      },
      "mvp_producers.mvp_movies[producer_id]":{
         "_href":"/api/v1/mvp_movies?producer_id={mvp_producers.id}",
         "_type":"mvp_movies"
      }
   },
   "mvp_genres_metadatas":[
      {
         "_id":3,
         "_href":"/api/v1/mvp_genres_metadatas/3",
         "_type":"mvp_genres_metadatas",
         "_etag":"VU1HSDNrmGehPDL5NGuCPA",
         "dateins":1428004164,
         "name":"Comedy",
         "genre_id":1,
         "language_id":1,
         "title":"Comedy",
         "_links":{
            "owner":5,
            "mvp_movies":[
               1
            ]
         }
      }
   ],
   "_linked":{
      "adm_users":[
         {
            "_id":5,
            "_href":"/api/v1/adm_users/5",
            "_type":"adm_users",
            "_etag":"o7J4Yd2dTZDnYbBQfCd7hg",
            "dateins":1427821405,
            "name":"Ingester",
            "enabled":true,
            "login":"user3",
            "password":"** sorry, can't serialize secret properties **",
            "company":null,
            "email":null,
            "initial_addin":null,
            "change_password":null,
            "passwordexpires":null,
            "_links":{
               "owner":1
            }
         }
      ],
      "mvp_movies":[
         {
            "_id":1,
            "_href":"/api/v1/mvp_movies/1",
            "_type":"mvp_movies",
            "_etag":"dGZ7xtiURiirFP8xq2hElw",
            "dateins":1428003470,
            "name":"Modern Times",
            "source":1,
            "duration":null,
            "release_date":null,
            "distributor_id":1,
            "country":null,
            "license_start":null,
            "license_end":null,
            "distributor_product_id":null,
            "type_id":null,
            "program":null,
            "theme":null,
            "original_title":null,
            "audience_type_id":null,
            "order":null,
            "season_id":null,
            "series_id":null,
            "season_asset_id":null,
            "series_asset_id":null,
            "content_category_id":null,
            "year":1978,
            "_links":{
               "owner":1,
               "producer_id":6
            }
         }
      ],
      "mvp_producers":[
         {
            "_id":6,
            "_href":"/api/v1/mvp_producers/6",
            "_type":"mvp_producers",
            "_etag":"VppHulNNpIziZM8gTCwwsA",
            "dateins":1428003277,
            "name":"Charles Chaplin Productions",
            "title":"Charles Chaplin Productions",
            "_links":{
               "owner":1
            }
         }
      ]
   }
}

5.2 - Sort order

Parameter "sort" is a highly customized way to sort order your results. By default a property will be sorted ascendingly, and descending must be informed with a minus ("-") sign before field name.

GET /api/v1/mvp_movies?sort=-year,name HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

The request above will be sorted first by descending year, and then by ascending name. If you include sublevels of your main object or list creating a compound document, each collection may have a sort order using the syntax sort[some_media_type]=name. Note that if you include the same media type in different levels, as sort order is by media type, the union of all collections will be sorted inside "linked" resources member, although the reference arrays will be sorted and showing only the correct items. You cannot use sort and sort[] mixed: once you specified one sort with media type, all sort sentences must be typed sort[media_type]. In case you want to sort with a related mediaType, you must use []. If there is more than one relationship with the same related mediaType, you need to specify the related column between brackets: sort[mainmediatype.relatedcolumn].

GET /api/v1/mvp_movies
?include=mvp_genres,mvp_producers
&sort[mvp_movies]=-year,name
&sort[mvp_genres]=-name
&sort[mvp_producers]=name HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Attention: above HTTP Header representation contains some extra line breaks for the sake of this document.

5.3 - Paging results

The main collection result will always be paged. By default, the page size has 20 items and first page will be returned when no page is specified. Parameter "page" is the zero-based index of the page to be returned, and parameter "pageSize" is the count of records per page, with minimum 1, default 20 and maximum 250; values outside this range will be turned into the default value. If the page is out of a valid range, an empty collection will be returned and you ll probably want to analyze the "meta" information to make a correct request.

GET /api/v1/mvp_genres?page=3&pageSize=5&sort=-id HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "_meta": {
    "_pageCount": 15,
    "_filterRowCount": 71,
    "_pageSize": 5,
    "_previousPage": "/api/v1/mvp_genres?page=2&pageSize=5&sort=-id",
    "_nextPage": "/api/v1/mvp_genres?page=4&pageSize=5&sort=-id",
    "_mainMediaType": "mvp_genres",
    "_ids": null,
    "_childMediaType": null,
    "_include": [],
    "_sortOrder": {
      "mvp_genres": [
        {
          "_sortType": "descending",
          "_columnName": "id"
        }
      ]
    },
    "_fields": {},
    "_filter": {
      "_root": {
        "operator": "and",
        "children": []
      }
    },
    "_page": 3,
    "_hideMeta": false,
    "_hideLinks": false,
    "contentSelection": null
  },
  "_links": {
    "mvp_genres.owner": {
      "_href": "/api/v1/adm_users/{mvp_genres.owner}",
      "_type": "adm_users"
    },
    "mvp_genres.content_selection_id": {
      "_href": "/api/v1/content_selection/{mvp_genres.content_selection_id}",
      "_type": "content_selection"
    },
    "mvp_genres.mvp_movies": {
      "_href": "/api/v1/mvp_genres/{mvp_genres.id}/mvp_movies",
      "_type": "mvp_movies"
    }
  },
  "mvp_genres": [
    {
      "_id": 1056,
      "_href": "/api/v1/mvp_genres/1056",
      "_type": "mvp_genres",
      "_etag": "s2J1UJd_vGw5D2X8tLzJ2g",
      "dateins": 1468347975,
      "name": "Action",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 1055,
      "_href": "/api/v1/mvp_genres/1055",
      "_type": "mvp_genres",
      "_etag": "elaK3CFXDlYY6gnlRuQP3Q",
      "dateins": 1468347975,
      "name": "Comedy",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 1054,
      "_href": "/api/v1/mvp_genres/1054",
      "_type": "mvp_genres",
      "_etag": "deWwrZOoMiC1PaetENJrOw",
      "dateins": 1468347403,
      "name": "Sci-fi",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 1053,
      "_href": "/api/v1/mvp_genres/1053",
      "_type": "mvp_genres",
      "_etag": "EDasaTE2489SvVAfWZ6s_A",
      "dateins": 1468347403,
      "name": "Action",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    },
    {
      "_id": 1052,
      "_href": "/api/v1/mvp_genres/1052",
      "_type": "mvp_genres",
      "_etag": "XgtWMtgFGkUbdFehgotLvw",
      "dateins": 1468347403,
      "name": "Comedy",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      }
    }
  ],
  "_linked": {},
  "_permissions": {
    "can_create": true
  }
}

As seen before, previousPage and nextPage links keep the filters, sort orders and all possible parameters informed in current request. Remember: as a zero-based index, if your pageCount is equals to 7, then your first page will be page=0 and your last page will be page=6. The last page may return less rows than pageSize.


5.4 - Hide metadata

Before your collection or main entity, API presents the metadata containing several informations about the query you made and paging data. You may want to reduce the network overhead and also server-side processing and query parameter hideMeta=1 allows you to avoid this extra member.


Before your collection or main entity, API presents the template links containing all URL's used to navigate from the main media type to its relateds. It's a very convenient way to discover all possible relationships and each API URL with a placeholder, but sometimes you may want to reduce the network overhead and also server-side processing and query parameter hideLinks=1 allows you to avoid this extra member.


5.6 - Sparse fieldset

Sometimes you may wish to query for a couple of fields rather than for the full entity. Applications of this need include drop-down-lists where "ID" and "Title" are enough, table views where you show just some fields, autocomplete text-boxes and many other situations. For these, you can use the parameter "fields" and ask for a limited comma-separated collection of fields for your main entity, or even for your associated media types. If you want to show your movie genres in a drop-down-list, you should use the following example:

GET /api/v1/mvp_genres_metadatas?hideMeta=1&hidelinks=1&pageSize=5&sort=name&fields=id,name HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "mvp_genres_metadatas": [
    {
      "_id": 1,
      "_href": "/api/v1/mvp_genres_metadatas/1",
      "_type": "mvp_genres_metadatas",
      "_etag": "DVEQCwwSxwgByrJsxSLdXQ",
      "name": "Action",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {}
    },
    {
      "_id": 2,
      "_href": "/api/v1/mvp_genres_metadatas/2",
      "_type": "mvp_genres_metadatas",
      "_etag": "8T6t23JrbPMWIRZHWu2dTg",
      "name": "Adventure",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {}
    },
    {
      "_id": 6,
      "_href": "/api/v1/mvp_genres_metadatas/6",
      "_type": "mvp_genres_metadatas",
      "_etag": "OhoQJuDRZ0JnlJlaCyYc2A",
      "name": "Animation",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {}
    },
    {
      "_id": 4,
      "_href": "/api/v1/mvp_genres_metadatas/4",
      "_type": "mvp_genres_metadatas",
      "_etag": "MwjV70IdngdRbjhW0vVNRA",
      "name": "Comedy",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {}
    },
    {
      "_id": 3,
      "_href": "/api/v1/mvp_genres_metadatas/3",
      "_type": "mvp_genres_metadatas",
      "_etag": "ys5Ix0xAiRXl66elOVpq6A",
      "name": "Drama",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {}
    }
  ],
  "_linked": {},
  "_permissions": {
    "can_create": true
  }
}

As you may see, pseudo-fields as "href" and "type" are displayed. Links under the resource (not the root links, which shows you the relationship metadata and is omitted here thanks to hideLinks=1 parameter) is an automatic pseudo-field, so if you have any relationship in your query sentence, it will be shown; for example, if you ask for "owner" field, as a related to adm_users media type it will be under "links" as in all previous examples. You can use fields[some_media_type] if you traverse to related using include parameter. Exactly as seen in Sort order chapter, you can't mix "fields" and "fields[]". If one media type is set to show only one field, a simple object or array will replace the linked relationship; if this single field is "id", the simple object will be an array of ids without a key. In the example below, some line breaks and spaces were added to HTTP header for the sake of this document.

GET /api/v1/mmedias/1014?hideMeta=1
 &hideLinks=1
       &include=mvp_movies
 &fields[mvp_movies]=name,year HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
If-None-Match: "r0Wv3r$10n0"
Accept: application/vnd.api+json

Response:

HTTP/1.1 200 OK
ETag: "r0Wv3r$10n1"
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "mmedias": [
    {
      "_id": 1014,
      "_href": "/api/v1/mmedias/1014",
      "_type": "mmedias",
      "_etag": "g3BggnLCJwHbH3N71u8gTA",
      "_url": "http://localhost/Upload/mmedias/00/00/00/1014_Piratas/",
      "dateins": 1470067538,
      "name": "piratas del caribe HD cut (local)",
      "ext": "FOLDER",
      "filesize": 164038,
      "filename": "smooth",
      "suffix": "_Piratas",
      "structured": 1,
      "storagearea": 0,
      "multiplefiles": 1,
      "width": null,
      "height": null,
      "duration": null,
      "title": null,
      "idref": null,
      "_playback_type": "SmoothStreaming",
      "_permissions": {
        "can_write": true,
        "can_delete": true
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        },
        "mvp_movies": {
          "operation": "Add",
          "values": [
            389,
            426,
            427
          ]
        }
      }
    }
  ],
  "_linked": {
    "mvp_movies": [
      {
        "_id": 426,
        "_href": "/api/v1/mvp_movies/426",
        "_type": "mvp_movies",
        "_etag": "SnptHevgaFKeLSiLYfSF1w",
        "name": "Monter Hunter: The Movie",
        "year": null,
        "_permissions": {
          "can_write": true,
          "can_delete": true
        },
        "_links": {}
      },
      {
        "_id": 389,
        "_href": "/api/v1/mvp_movies/389",
        "_type": "mvp_movies",
        "_etag": "Z2sDnWDzYnpmeO0rMMfyuw",
        "name": "Inception",
        "year": null,
        "_permissions": {
          "can_write": true,
          "can_delete": true
        },
        "_links": {}
      },
      {
        "_id": 427,
        "_href": "/api/v1/mvp_movies/427",
        "_type": "mvp_movies",
        "_etag": "ZybfnH3YqpVE_yCYWONPHQ",
        "name": "The Book of Eli",
        "year": null,
        "_permissions": {
          "can_write": true,
          "can_delete": true
        },
        "_links": {}
      }
    ]
  }
}

Pay attention to mmedias relation with movie using only the "name,year" property: you get a simple object with a key-value pair "field":"value". If a movie could have more than one producer ("to-many" relationship), you should see an array of id values:

"links": {
      "mvp_movies": {
          "operation": "Add",
          "values": [ 389, 426, 427 ]
        }
}

If you ask for a "to-one" relationship, you get the pure id value:

"links": {
      "owner": {
            "operation": "Add",
            "values": 1
          }
}

If you ask for a "to-many" relationship, you get an array of id values:

"links": {
  "producer_id": [ 38, 314, 123 ]
}

Remember that fields[some_media_type] is evaluated to all instances of that media type, in any relationship level or path. If you show some media type in more than one path, the rule will be applied to all of them.


5.7 - Filter results

Frequently we need a complex query allowing our users to customize filters and predicates. For filtering based upon strict matching (equals to) you should use the field name as a parameter and its desired value URL-encoded. Each field exposed as key of key-value parameter will be evaluated using "AND" clause in the predicate. That said, if we want filter all movies produced by Warner (id 1) in United States, we should use the following query:

GET /api/v1/mvp_movies?producer_id=1&country=United%20States HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

However, sometimes this is not enough and you may want a different matching type, as "greater-than", "greater-or-equals-to", "starts-with" and other rules. Parameter "filter" provides a syntax where client will inform all the filter rules and get the results according with its needs. Suppose we now have to find the previous list (produced by Warner in United States) but only those released in 2014 or after. The following HTTP header contains extra line breaks.

GET /api/v1/mvp_movies?filter=producer_id_$eq_1_$and_country_$eq_United%20States_$and_release_date_$ge_2014-01-01 HTTP/1.1
Host: mediaibox.mydomain.comHa
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

You can mix between strict-only query and filter expression. The value must be always URL encoded (RFC 1738), so "United States" becomes "United%20States". Dates can be represented as yyyy-MM-dd format or as Unix Time if you want more precision.


5.7.1 - Expressions

$eq ⇒ Equals to (Name = 'Scarlett')

$neq ⇒ Not equals to (Name != 'Scarlett')

$gt ⇒ Greater than (Birthdate > '2015-01-01')

$ge ⇒ Greater or equals to (Birthdate >= '2015-01-01')

$lt ⇒ Lower than (Birthdate < '2015-01-01')

$le ⇒ Lower or equals to (Birthdate <= '2015-01-01')

$lk ⇒ Likes (Name LIKE 'Sca%'). Use '' as '%' sign, e.g., _$lk_Sca

$sw ⇒ Starts with (same as _$lk_Sentence*)

$ew ⇒ Ends with (same as $lk*Sentence)

$ct ⇒ Contains (same as $lkSentence)

$and ⇒ AND Expression

$or ⇒ OR Expression

_$in(1,2,3,4,5,9) ⇒ IN Expression, use comma-separated values

$esc(x) ⇒ Ignore specific character (*)

$isempty⇒ Is empty or not (accept only true/false values) (Year_$isempty_true)

parentheses ⇒ Groups "and's" and "or's" sentences as needed.

  • There is possibility to escape characters in particular on the values of operation.

    ie:

           name_$lk_foo(bar)foo
    

    The API will handle the parentheses as a grouping of operations in interpreting the above

    operation, thereby generating errors when processing. To avoid such problems it is

    advisable to use 'escape' operator. Below the filter with 'escape' operator applied.

          name_$lk_foo_$esc(()_bar_$esc())_foo
    

    The escape operator should be used only in the sentence of values.

    The structure of the escape operator is as follows:

          _$esc(X)_ ⇒ X is the character that will be ignored in the interpretation of the API  
    
                              process.
    

Examples:

Field name equals to Scarlett ⇒ name_$eq_Scarlett

Field name not equals to Alicia ⇒ name_$neq_Alicia

Field age greater than 15 ⇒ age_$gt_15

Field age greater than or equals to 18 ⇒ age_$ge_18

Field date before year 2000 ⇒ date_$lt_2000-01-01

Field date before or equals to 2000-01-01 12:30:00 ⇒ date_$le_946729800

Field genre_name is like Science Fiction, ignoring case ⇒ genre_name_$lk_science%20fiction

Field name starts with M, ignoring case ⇒ name_$sw_m

Field surname ends with "son", ignoring case ⇒ name_$ew_son

Field full_name contains " von ", ignoring case ⇒ full_name_$ct_%20von%20

Field age between 15 (inclusive) and 18 (inclusive) ⇒ age_$ge_15_$and_age_$le_18

Field name equals to Ann or surname contains Ann ⇒ name_$eq_Ann_$or_surname_$ct_Ann

Field year is in a list ⇒ year_$in(1958,1962,1970,1994,2002)

Men called John and women called Jane ⇒ ?filter=(name_$eq_John_$and_sex_$lk_m)$or(name_$eq_Jane_$and_sex_$lk_f)

Field Year is empty ⇒ year_$isempty_true

Field Year is not empty ⇒ year_$isempty_false


5.7.2 - Including inherited children

It is possible to include children defined by a field-value relationship with their parents in the filters. Through in or notin operator, a parent and its children can be included in the search, in which is also possible to define the relationship-defining field and the relationship grade (treated as depth here, as the search is based on a tree with the parent as the root).

Syntax samples:

$in({value}:{depth})

$in({value}:[columnName])

$in({value}:[columnName]{depth})

$in({value}:{depth}[columnName])

Where:

value: value considered as the root of the tree (parent value)

depth: (int) size of the search tree; relationship grade limit in which children will be included

defaultValue and maxValue may be defined in ChildFilterConfig

If there is no definition/config file, defaultValue = maxValue = 10

If depth = 0, depth = maxValue

If there is no depth as defined by the syntax, depth = defaultValue

If depth > maxValue, depth = maxValue

columnName: (string) defines which column will be used as the relationship-defining field

If there is no columnName as defined by the syntax, columnName = PARENT

Example

Considering the existing tables below:

TableA

ID PARENT ORIGIN
1
2 1 1
3 2 1
4
5 3 2
6 4 2
7 4 3
8 5 3
9 4
10 4
11 4 7
12 4 8
13 8 5

TableB

ID POSITION
1 1
2 3
3 6
4 11
5 13

(Position relates do TableA[ID])

Queries

tableA?filter=id_$in(2:2)
:includes id = {2,3,5}

tableA?filter=id_$in(2[ORIGIN]:2)
:includes id = {2,5,6,10,13}

tableB?filter=position_$in(3:0)
:includes position = {3,5,8,13}
:returns id = {2,5}

tableB?filter=position_$in(3:0[ORIGIN)
:includes position = {3,8,7,11,12}
:returns id = {2,4}


5.8 - Ignore ADM_FIELDS

It may be desired to get data only if there is a relationship between two entities, when they are linked through a LinkObject. This can be achieved by passing ignoreadmfields as true in the query string, however this options is orthogonal to includes and will be ignored if any include is used.

/api/v1/sources/406/gvp_cdn_delivery_buckets?ignoreadmfields=true

6 - Read a collection from a field relation

It is possible to return a listing through a relation field (ADM_FIELDS of type Related|DropRelated|Source), that is, search the movies where the name of the source is 'root'.

/api/v1/gvp_movies?filter=source[name]_$eq_root

The name of related field is enclosed in brackets, thus making it possible to use any other field of preference.


7 - Create a new entity

Through a HTTP POST request you can insert a new record into the MibServer. This is a synchronous operation and result in a HTTP 40x code with an error message or in a HTTP 201 Created message when success, with the new ID.

POST /api/v1/mvp_genres HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{  
   "mvp_genres":[  
      {  
         "name":"Mistery"
      }
   ]
}

Successful response:

HTTP/1.1 201 Created
Location: /api/v1/mvp_genres/36
ETag: "r0Wv3r$10n0"
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "_meta":{
      "_pageCount":1,
      "_filterRowCount":1,
      "_pageSize":20,
      "_previousPage":"",
      "_nextPage":"",
      "_mainMediaType":"mvp_genres",
      "_ids":[
         1002
      ],
      "_childMediaType":null,
      "_include":[
      ],
      "_sortOrder":{
      },
      "_fields":{
      },
      "_filter":{
         "_root":null
      },
      "_page":0,
      "_hideMeta":false,
      "_hideLinks":false
   },
   "_links":{
      "mvp_genres.owner":{
         "_href":"/api/v1/adm_users/{mvp_genres.owner}",
         "_type":"adm_users"
      }
   },
   "mvp_genres":[
      {
         "_id":1002,
         "_href":"/api/v1/mvp_genres/1002",
         "_type":"mvp_genres",
         "_etag":"mL0kB2wTM-khk8Eb7IArVg",
         "dateins":1430929191,
         "name":"Mistery",
         "_links":{
            "owner":1
         }
      }
   ],
   "_linked":{
   }
}

Not all fields are required; read-only fields are ignored. Related objects can be informed the same way they were read before.

POST /api/v1/adm_enumtypes HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{  
   "adm_enumtypes":[  
      {  
         "name":"numbers",
         "_links":{  
            "Adm_enumvalues[enumtype_id]":{
"values" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
}
         }
      }
   ]
}

Very easy when you know remote ID and media-type. But sometimes you don't know this information, or want several related records by filter without knowing their IDs. In this case, your related object can be of type "finder".

POST /api/v1/mvp_genres HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
   "mvp_genres_metadatas":[
      {
         "name":"Action",
         "title":"Action",
         "_links":{
            "mvp_movies":[
               {
                  "_type":"finder",
                  "_href":"/api/v1/mvp_movies?filter=name_$lk_avengers",
                  "_field":"id",
                  "_resultset":"all"
               }
            ]
         }
      }
   ]
}

New genre Comedy will be created and associated to all Hangover movies.

If you choose resultset "all", then all items from query will be related, if you choose firstOrDefault or lastOrDefault, only one item will be related.

When "all" is chosen, the finder has a different behaviour over default query system: the results are not paged by default, so if you have hundreds of items returned by query, all of them will be related, not only the first 20. You can change this behaviour forcing parameters page and pageSize.

Note that mvp_movies is related to a collection of movies (to-many relationship), so you can use several finder and static objects in an array. If your relationship property is a "to-one", you must use a single finder object with firstOrDefault or lastOrDefault resultset value.

POST /api/v1/mvp_movies HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
   "mvp_movies":[
      {
         "name":"Inception",
         "country":"USA",
         "year":"2010",
         "_links":{
            "producer_id":[
               {
                  "_type":"finder",
                  "_href":"/api/v1/mvp_producers?filter=name_$lk_warner*",
                  "_field":"id",
                  "_resultset":"firstOrDefault"
               }
            ],
            "mvp_genres_metadatas":[
               {
                  "_type":"finder",                  "_href":"/api/v1/mvp_genres_metadatas?filter=name_$lk_action",
                  "_field":"id",
                  "_resultset":"firstOrDefault"
               },
               {
                  "_type":"finder",                  "_href":"/api/v1/mvp_genres_metadatas?filter=name_$lk_adventure",
                  "_field":"id",
                  "_resultset":"firstOrDefault"
               },
               {
                  "_type":"finder",
                "_href":"/api/v1/mvp_genres_metadatas?filter=name_$lk_sci-fi",
                  "_field":"id",
                  "_resultset":"firstOrDefault"
               }
            ]
         }
      }
   ]
}

In previous example, producer_id is a property (field) and points to a finder object (not array), while mvp_genres is a media type name (after all, there's no property concept in a many-to-many relationship) and it's an array of finders.

In batch operations you will learn about another dynamic linking object, that can be used together with "finder".


8 - Create multiple entities

If your root media-type named resource is an array, multiple entities will be created in a transaction: once an exception is thrown, none of the entities will be saved. Response "Location" header no longer corresponds to a single object but multiple ids, and response body has details of each entity.

POST /api/v1/mvp_genres HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
{
  "mvp_genres_metadatas": [{
    "name": "Comedy",
    "title": "Comedy"
  }, {
    "name": "Action",
    "title": "Action"
  }, {
    "name": "Sci-fi",
    "title": "Sci-fi",
  }]
}

Response:

HTTP/1.1 201 Created
Location: /api/v1/mvp_genres/39,40,41
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "_meta":{
      "_pageCount":1,
      "_filterRowCount":3,
      "_pageSize":20,
      "_previousPage":"",
      "_nextPage":"",
      "_mainMediaType":"mvp_genres_metadatas",
      "_ids":[
         1015,
         1016,
         1017
      ],
      "_childMediaType":null,
      "_include":[
      ],
      "_sortOrder":{
      },
      "_fields":{
      },
      "_filter":{
         "_root":null
      },
      "_page":0,
      "_hideMeta":false,
      "_hideLinks":false
   },
   "_links":{
      "mvp_genres_metadatas.owner":{
         "_href":"/api/v1/adm_users/{mvp_genres_metadatas.owner}",
         "_type":"adm_users"
      },
      "mvp_genres_metadatas.mvp_movies":{
         "_href":"/api/v1/mvp_genres_metadatas/{mvp_genres_metadatas.id}/mvp_movies",
         "_type":"mvp_movies"
      }
   },
   "mvp_genres_metadatas":[
      {
         "_id":1016,
         "_href":"/api/v1/mvp_genres_metadatas/1016",
         "_type":"mvp_genres_metadatas",
         "_etag":"96ifz_tjcfG5JEAdoBMWVA",
         "dateins":1431037784,
         "name":"Action 1",
         "genre_id":null,
         "language_id":null,
         "title":"Action 1",
         "_links":{
            "owner":1
         }
      },
      {
         "_id":1015,
         "_href":"/api/v1/mvp_genres_metadatas/1015",
         "_type":"mvp_genres_metadatas",
         "_etag":"rYeseuQbV6jWQXruN-LenA",
         "dateins":1431037781,
         "name":"Comedy 1",
         "genre_id":null,
         "language_id":null,
         "title":"Comedy 1",
         "_links":{
            "owner":1
         }
      },
      {
         "_id":1017,
         "_href":"/api/v1/mvp_genres_metadatas/1017",
         "_type":"mvp_genres_metadatas",
         "_etag":"393pG6P7HYhbKm6EuiqbVg",
         "dateins":1431037785,
         "name":"Sci-fi 1",
         "genre_id":null,
         "language_id":null,
         "title":"Sci-fi 1",
         "_links":{
            "owner":1
         }
      }
   ],
   "_linked":{
   }
}

9 - File upload

Some media-types are attached to one or more files. There are three ways to upload files and create a related media-type object in MibServer API.

9.1 - Inline file upload

If you have a couple of small local files and want to upload them at once including media-type metadata, you can create a single HTTP POST including the base64 encoded files as links to the files.

Let's pretend that mvp_producers media-type has two associated images: Icon and Logo. We want to upload both as PNG files while creating the producer record.

POST /api/v1/mmedias HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"mmedias - icoArrowRight.gif",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"inline",
                  "_filename":"icoArrowRight.gif",
                  "_fileSize":61,
                  "_md5":"A664C489D57881409C9AB30D1A2C14ED",
                  "_base64Data":"R0lGODlhCwALAIAAAOvr6wBqwCH5BAEAAAAALAAAAAALAAsAAAIUhB2nF8kN24sQ0Qiu3pn3uzwhsxQAOw=="
               }
            ]
         }
      },
            {
         "name":"mmedias - icoEdit.gif",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"inline",
                  "_filename":"icoEdit.gif",
                  "_fileSize":77,
                  "_md5":"8C73B7FF1D9AA53B8546E2FFD909A2F0",
                "_base64Data":"R0lGODlhDgAOAJEAAGVlZURERPT09Obm5iH5BAAAAAAALAAAAAAOAA4AAAIelI+pywbRXIDtUWZjRqP3GXiiB46jZZ5AKq7sC8cFADs="
               }
            ]
         }
      }
   ]
}

You can create multiples entities at the same time, but avoid big files using this method, you will probably face timeout or connection breakdown problems.


9.2 - Upload lazily

It is also possible to upload all files directly to the desired storage area, while using the API to register the content in the database. This can be achieved through a lazy upload type, where the API creates the desired metadata without managing files directly.

Just like when using inline upload, one must send an HTTP POST request with the desired files, however no data is actually transmitted. Note that the type of the upload must be set to lazy .

POST /api/v1/mmedias HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"mmedias - icoArrowRight.gif",
         "_keywords":"New,Content,Upload,API,Test",
         "source":1,
         "_links":{
            "_files":[
               {
                  "_type":"lazy",
                  "_filename":"icoArrowRight.gif",
                  "_fileSize":61
               }
            ]
         }
      },
      {
         "name":"mmedias - icoEdit.gif",
         "_keywords":"New,Content,Upload,API,Test",
         "source":1,
         "_links":{
            "_files":[
               {
                  "_type":"lazy",
                  "_filename":"icoEdit.gif",
                  "_fileSize":77
               }
            ]
         }
      }
   ]
}

The API will return with the ID of the created entity, which then can be used to get the information of its storage area through an HTTP GET request:

GET /api/v1/fullstoragearea/{contentMediaType}/{contentId}
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

And its response:

{
    "Type": 1, // 0 = disk, 1 = amazons3, 2 = azure
    "Path": "bucketname/subfolder", // bucket with path or disk path
    "Username": "4Cc35sK31", // key for Amazon/Azure
    "Password": "53cR37k311", // secret for Amazon/Azure
    "Permission": 1, // 0 = public, 1 = private
    "ExtraSettings": {} // amazons3 region
}

If multiple files are being uploaded, a folder named {ID}{SUFFIX} must be created and all files must be uploaded into it. For example, 1234_639E4E071EFA4F24.

If only one file is to be uploaded, a single file named {ID}{SUFFIX}{EXTENSION} must be uploaded. For example, 1234_639E4E071EFA4F24.mp4.

Both ID and suffix are in the response from the HTTP POST request.

After directly uploading the files, its is necessary to confirm with the API if the files were correctly uploaded through an HTTP PUT request:

PUT /api/v1/$checkupload/{contentMediaType}/{contentId}
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
{
   "_filesToValidate":{
      "icoArrowRight.gif":{
         "Item1":61, // filesize
         "Item2":"A664C489D57881409C9AB30D1A2C14ED" // md5
      },
      "icoEdit.gif":{
         "Item1":77,
         "Item2":"8C73B7FF1D9AA53B8546E2FFD909A2F0"
      }
   }
}

The filesize and MD5 will be checked by the API, and if everything matches it will consider the upload completed and update the object accordingly, if it fails an error will be received. By default all MD5 information is required, however this can be disabled with the forceCheckMd5OnUploadComplete API configuration.

When mixing this type of upload with any other, the information of all files (not just those with type lazy ) must be sent in the final HTTP PUT request.

9.3 - Upload from cloud

This method is recommended if your files are available online. Remember that an upload operation is always synchronous, so your connection must have a high timeout because it waits for the copy from cloud to MibServer disk before returning.

From a S3:

POST /api/v1/mmedias HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
     {
            "name": "mmedias - image.png",
            "_keywords": "New,Content,Upload,API,Test",
            "_links": {
                "source": 1,
                "_files":[{
                    "_type": "amazons3",
                    "_filename":"image.png",
                    "_filesize": 47042,
                    "_accessKey":"4Cc35sK31",
                    "_secretKey":"53cR37k311",
                    "_bucket":"MibServer2Tests",
                    "_region":"useast1",
                    "_subfolder":"/IMAGES/00/00/00",
                    "_storagearea": 0,
                    "_md5":"7FE0EC0EA5D344C734555934F12183C3"
                }]
            }
        },
        {
            "name": "mmedias - labone.png",
            "_keywords": "New,Content,Upload,API,Test",
            "_links": {
                "source": 1,
                "_files":[{
                    "_type": "amazons3",
                    "_filename":"labone.png",
                    "_filesize": 3387,
                    "_accessKey":"4Cc35sK31",
                    "_secretKey":"53cR37k311",
                    "_bucket":"MibServer2Tests",
                    "_region":"useast1",
                    "_subfolder":"/IMAGES/00/00/00",
                    "_storagearea": 0,
                    "_md5":"29140D855EAB347BC7E861247AE2B8C2"
                }]
            }
        }
   ]
}

The following are valid values for the region property:

- apnortheast1
- apsoutheast1
- apsoutheast2
- cnnorth1
- eucentral1
- euwest1
- saeast1
- useast1
- usgovcloudwest1
- uswest1
- uswest2

If this parameter is ommited, useast1 will be used as default.

From a blob in Azure:

POST /api/v1/mvp_producers HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"mmedias - image.png",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"azureblob",
                  "_filename":"image.png",
                  "_filesize":13982,
                  "_accountName":"4cC0uN7n4M3",
                  "_accountKey":"4cC0uN7k31",
                  "_bucket":"mibserverapitests",
                  "_subfolder":"StorageArea0",
                  "_storagearea":0,
                  "_md5":"1D099CB0AC994728D87F424A0E57FC30"
               }
            ]
         }
      },
      {
         "name":"mmedias - sample_x264_aac.mp4",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"azureblob",
                  "_filename":"sample_x264_aac.mp4",
                  "_filesize":3352080,
                  "_accountName":"4cC0uN7n4M3",
                  "_accountKey":"4cC0uN7k31",
                  "_bucket":"mibserverapitests",
                  "_subfolder":"StorageArea0",
                  "_storagearea":1,
                  "_md5":"009286C3DB8E6543C5587B1CA6F37854"
               }
            ]
         }
      }
   ]
}

The following are valid values for the region property:

- apnortheast1
- apsoutheast1
- apsoutheast2
- cnnorth1
- eucentral1
- euwest1
- saeast1
- useast1
- usgovcloudwest1
- uswest1
- uswest2

If this parameter is ommited, useast1 will be used as default.

From a WebDAV:

POST /api/v1/mvp_producers HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"mmedias - movistar.pngg",
         "_keywords":"New,Content,Upload,API",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"web",
                  "_filename":"movistar.png",
                  "_storagearea":1,
                  "_password", "p45sW0rD",
                  "_user", "u53R",
"_url":"http://www.telefonica.com/img/marcas/lgo_movistar_at.png",
                  "_md5":"96D96C20D93DB07CC43F34FA7124DB04"
               }
            ]
         }
      },
      {
         "name":"mmedias - vivo.pngg",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"web",
                  "_filename":"vivo.png",
                  "_storagearea":1,
                  "_password", "p45sW0rD",
                  "_user", "u53R",
"_url":"http://www.telefonica.com/img/marcas/lgo_vivo_at.png",
                  "_md5":"7F6A305557AC95A14793763D93FBF738"
               }
            ]
         }
      }
   ]
}

From a FTP:

POST /api/v1/mvp_producers HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"mmedias - favico.ico",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"ftp",
                  "_filename":"favico.ico",
                  "_filesize":41,
                  "_storagearea":1,
                  "_server":"ftp.server",
                  "_port":21,
                  "_subfolder":"Medias",
                  "_user":"u53r",
                  "_password":"p4s5w0Rd",
"_ssl":false,
"_passive":true,
                  "_md5":"F1E37027B401D9702DC8C0A9E75575D5"
               }
            ]
         }
      },
      {
         "name":"mmedias - ico.ico",
         "_keywords":"New,Content,Upload,API,Test",
         "_links":{
            "source":1,
            "_files":[
               {
                  "_type":"ftp",
                  "_filename":"ico.ico",
                  "_filesize":41,
                  "_storagearea":1,
                  "_server":"ftp.server",
                  "_port":21,
                  "_subfolder":"/Media/00/00/00",
                  "_user":"u53r",
                  "_password":"p4s5w0Rd",
"_ssl":false,
"_passive":true,
                  "_md5":"F1E37027B401D9702DC8C0A9E75575D5"
               }
            ]
         }
      }
   ]
}

You are allowed to mix between different cloud storages for each file, and even mix this method with previously shown Inline file upload and Upload lazily.


9.4 - Resumable upload

If you have large files in your local disk you want to use resumable upload in order to send small chunks along different requests and avoid timeout problems. First, you will announce your intention to use resumable upload, then you will send each chunk of each file and finally you will close the upload sending your metadata with all references.


9.4.1 - Start a resumable upload

You must execute a HTTP POST to /api/v1/$upload with all files you will upload and get an unique transaction identifier, which will be used in every chunk you send.

POST /api/v1/$upload HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "_files": [ "logo.png", "icon.png" ]
}

Response:

HTTP/1.1 200 OK
Location: /api/v1/$upload/0250bf08-4272-4f55-a8e3-585b917f0445
Content-Type: application/vnd.api+json;charset=UTF-8
{  
   "_files":[{  
         "_id":"4668aaaa-cf49-4396-a108-c14c14bc8df3/logo.png",
       "_href":"/api/v1/$upload/4668aaaa-cf49-4396-a108-c14c14bc8df3/logo.png"
      },
      {  
         "_id":"4668aaaa-cf49-4396-a108-c14c14bc8df3/icon.png",
       "_href":"/api/v1/$upload/4668aaaa-cf49-4396-a108-c14c14bc8df3/icon.png"
      }]
}

9.4.2 - Send chunks

You may choose your chunk size according to your network conditions and your HTTP restrictions. When you send a chunk, you create a HTTP PUT to file's URL ("href" field of previous response), you send the chunk size, range, MD5 and type as HTTP Headers, and the body must be the base64 encoded chunk itself.

PUT /api/v1/$upload/0250bf08-4272-4f55-a8e3-585b917f0445/logo.png HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Disposition: form-data; name="logo"; filename="logo.png"
Content-Type: application/octet-stream
Content-Length: 200000
Content-MD5: chunk_md5
Content-Range: bytes 0-200000/1424858
<BINARY>

Response for chunk received but file still incomplete:

HTTP/1.1 206 Partial Content
Content-Length: 0
Range: 0-200000

Response for file complete:

HTTP/1.1 201 Created
Content-Length: 0

9.4.3 - Save metadata with files

After all files uploaded, you have to POST your metadata with the references to them. You may use "id" field, "href" field, or both, and type should be uploaded.

POST /api/v1/mmedias HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mmedias":[
      {
         "name":"Warner Bros.",
         "_links":{
            "_files":[
               {
                  "_type":"resumable",
                  "_filename":"icon.png",
                  "_md5":"logofilemd5",
                  "_filesize":1424858,
                  "_id":"0250bf08-4272-4f55-a8e3-585b917f0445/icon.png"
               },
               {
                  "_type":"resumable",
                  "_filename":"logo.png",
                  "_md5":"logofilemd5",
                  "_filesize":1424858,
                  "_id":"0250bf08-4272-4f55-a8e3-585b917f0445/logo.png"
               }
            ]
         }
      }
   ]
}

9.5 - Upload content in a separate API call

You may also upload files after their metadata is sent to API through an Insert call. This operation is available in a HTTP PUT request, because it updates already sent data. If the operation was succesful, a HttpStatusCode OK will be returned, otherwise a HttpStatusCode NotModified will be returned.

PUT /api/v1/$contentupload/images/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "_collection":[
      
               {
                  "_type":"inline",
                  "_filename":"icoArrowRight.gif",
                  "_fileSize":61,
                  "_md5":"A664C489D57881409C9AB30D1A2C14ED",                   "_base64Data":"R0lGODlhCwALAIAAAOvr6wBqwCH5BAEAAAAALAAAAAALAAsAAAIUhB2nF8kN24sQ0Qiu3pn3uzwhsxQAOw=="
               }
            ]
         
 }

10 - Update an existing entity

Through a HTTP PUT request you can update an existing record in the MibServer. This is a synchronous operation and results in a HTTP 40x code with an error message or in a HTTP 204 No Content message when successful. All fields are required, if you don't send a field, it will be nulled.

PUT /api/v1/mvp_genres_metadatas/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mvp_genres_metadatas":[
      {
         "_id":1,
         "name":"Comedy",
         "title":"Comedy"
      }
   ]
}

Successful response:

HTTP/1.1 204 No Content
Location: /api/v1/mvp_genres/1
ETag: "r0Wv3r$10n1"

If you want to ensure that your entity version wasn't modified since you got it, you can use ETag header when read and If-Match when update. For more details see the chapter HTTP ETags and look for collision detection.

PUT /api/v1/mvp_genres_metadatas/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
If-Match: "r0Wv3r$10n0"
{
   "mvp_genres_metadatas":[
      {
         "_id":1,
         "name":"Comedy",
         "title":"Comedy"
      }
   ]
}

Successful response is equivalent to the last example, with a new ETag version though. Conflict error will be returned if the row version is different or if the record was deleted in the meantime.

HTTP/1.1 409 Conflict
Content-Type: application/vnd.api+json
{
   "error":"entity_invalidetag",
   "error_message":"[Entity/InvalidEtag]"
}

A 409 Conflict may be returned even if you don't pass If-Match header when the record was deleted in meantime, so you want to treat this exception.

HTTP/1.1 409 Conflict
Content-Type: application/vnd.api+json
{
   "error": "delete_itemnotfound",
   "error_message": "Record was deleted in meantime."
}

When updating a record, its relationships can be modified. If you send a related object in "links", all references will be changed according to the new values.

PUT /api/v1/mvp_movies/139 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
If-Match: "r0Wv3r$10n0"
{
   "mvp_movies":[
      {
         "_id":139,
         "name":"Modern Times",
         "country":"USA",
         "year":"1936",
         "_links":{
            "producer_id":6,
            "mvp_genres_metadatas":[ 11,15,29 ]
         }
      }
   ]
}

Attention: all non-listed ids will be unlinked, so take careful with your array, because if you send an empty array as mvp_genres property above, your movie will end up without genres. If you don't want to change the genres of a movie, just don't put such property inside "links".

"Finders" as seen in Create a new entity chapter are perfectly valid here.

10.1 - Set field as null

If you want to set any nullable field to null, you can send a request with the field set as a #null string. For example:

PUT /api/v1/mvp_genres_metadatas/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
   "mvp_genres_metadatas":[
      {
         "_id":1,
         "name":"#null",
         "number":"#null",
         "releasedate":"#null"
      }
   ]
}

This will set those values to NULL in the database, if it is allowed by the schema.


11 - Update multiple entities

Similar to that seen in Create multiple entities, you can update multiple entities of the same media type in one single request using an array. The PUT URL must have all ids to be changed comma-separated. Every entity in the array must have an id property this time.

PUT /api/v1/mvp_genres_metadatas/1,5,9 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
If-Match: "r0Wv3r$10n0"
{
   "mvp_genres_metadatas":[
      {
         "_id":1,
         "name":"Comedy"
      },
      {
         "_id":5,
         "name":"Action"
      },
      {
         "_id":9,
         "name":"Sci-fi"
      }
   ]
}

12 - Delete an existing entity

Through a HTTP DELETE request you can remove an existing record from the MibServer. This is a synchronous operation and result in a HTTP 40x code with an error message or in a HTTP 204 No Content message when success.

DELETE /api/v1/mvp_genres_metadatas/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Successful response:

HTTP/1.1 204 No Content

If you want to ensure that your entity version wasn't modified since you got it, you can use ETag header when read and If-Match when delete. For more details see the chapter HTTP ETags and look for collision detection.

DELETE /api/v1/mvp_genres/1 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
If-Match: "r0Wv3r$10n0"

Successful response is equivalent to the last example (a simple 204 code). Conflict error will be returned if the row version is different or if the record was deleted in the meantime.

HTTP/1.1 409 Conflict
Content-Type: application/vnd.api+json
{
   "error": "delete_itemnotfound",
   "error_message": "Record was changed in meantime."
}

A 409 Conflict may be returned even if you don't pass If-Match header when the record was deleted in meantime, so you want to treat this exception.

HTTP/1.1 409 Conflict
Content-Type: application/vnd.api+json
{
   "error": "delete_itemnotfound",
   "error_message": "Record was deleted in meantime."
}

There are no restrictions other than the permissions already known and presented. For more information click here to view permissions by user and here to view permissions by media type.


13 - Delete multiple entities

Using comma-separated ids in the end of a DELETE URL, multiple entities will be deleted at once.

DELETE /api/v1/mvp_genres/45,76,98 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

14 - Add, remove or replace relationships

When you update an entity, if you use a related media type inside "links", all your relationships between both media types will be replaced by those ids, removing or adding as needed. If you want to have more control and add or remove an specific relationship, or even replace all relationships between two objects without updating the entity itself, you have to POST, PUT or DELETE to the URL /api/v1/parent_media_type/4/related_media_type. POST will add the listed relationships, PUT will replace all the current relationships for new listed values, and DELETE will evidently remove the listed relationships. Suppose we have a comedy genre (id 1) related to movies 5, 6 and 7. Now we want to simply add the 22 movie there.

POST /api/v1/mvp_genres/1/mvp_movies HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{
  "mvp_movies": {
      "operation": "Add",
      "values": [ 5, 6, 7, 22 ]
   }
}

Now, movies 5, 6, 7 and 22 are related to Comedy genre. If the method were PUT instead of POST, then movies 5, 6 and 7 were no longer related to Comedy, only 22. POST adds, PUT replaces. But we used POST, and now there are 4 comedy movies.

Suppose that movies 6 and 7 are there but they shouldn't be. We may execute a PUT using 5 and 22, but sometimes is easier to simply DELETE the movies 6 and 7 from comedy.

DELETE /api/v1/mvp_genres/1/mvp_movies/6,7 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

DELETE method doesn't have a body, you must use the ids inside URL, comma-separated.


It is also possible to update the relationships via links. The following is an example where the movie with id 4858 will be related to the genres 1020, 1021 and 1034:

PUT /api/v1/mvp_movies/4858 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json;charset=UTF-8
{ 
    "mvp_movies": 
    [
        {
            "_id": 4858,
            "_links": 
            {
                  "mvp_genres" : 
                  {
                  "operation" : "Replace",
                        "values": [ 1020, 1021, 1034 ]
                  }  
}          
        }
    ]
}

Note that the "operation" field has been entered, this field informs how the related data should be handled. The supported operators and their respective descriptions are:

  • Add (Only adds relationships)

  • Replace (Remove all existing relationships and inserts new relationships with the informed values)

  • Remove (Remove all relationships except the informed values)

Obs: The default operation is "Add".


16 - Entity Inheritance

If some media type is marked as inherited from another (overriding one or more properties), when you request the parent you won't see the child, but if you request the child you will get the whole parent inside a property "inherits" of the entity document. It's up to you to use the child's values, the parent's values or merge both as MibServer2 does.

GET /api/v1/mvp_movies_extension/2?hideLinks=true&hideMeta=true
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json

Response:

{
  "mvp_movies_extension": [
    {
      "_id": 2,
      "_href": "/api/v1/mvp_movies_extension/2",
      "_type": "mvp_movies_extension",
      "_etag": "43joLmdh5njUGJ2k6Ms2Hg",
      "dateins": 1474474259,
      "name": "movie extension",
      "source": 1,
      "duration": null,
      "release_date": -79200,
      "producer_id": null,
      "country": null,
      "license_start": 0,
      "license_end": 0,
      "distributor_product_id": null,
      "type_id": null,
      "program": null,
      "theme": null,
      "original_title": null,
      "audience_type_id": null,
      "order": null,
      "season_id": null,
      "series_id": null,
      "season_asset_id": null,
      "series_asset_id": null,
      "content_category_id": null,
      "year": 2018,
      "mib_parent_id": 383,
      "_permissions": {
        "can_write": false,
        "can_delete": false
      },
      "_links": {
        "owner": {
          "operation": "Add",
          "values": 1
        }
      },
      "_inherits": {
        "_id": 383,
        "_href": "/api/v1/mvp_movies/383",
        "_type": "mvp_movies",
        "_etag": "kUJnMMAQ6G4rYmSJuIP8YA",
        "dateins": 1469227646,
        "name": "Movie",
        "duration": null,
        "release_date": null,
        "country": null,
        "license_start": null,
        "license_end": null,
        "distributor_product_id": null,
        "type_id": null,
        "program": null,
        "theme": null,
        "original_title": null,
        "audience_type_id": null,
        "order": null,
        "season_asset_id": null,
        "series_asset_id": null,
        "year": 2016,
        "category": null,
        "billing_id": null,
        "content_selection_id": 1265,
        "test_date": 1468292400,
        "test_boolean": 0,
        "_links": {
          "owner": {
            "operation": "Add",
            "values": 1
          },
          "source": {
            "operation": "Add",
            "values": 1
          }
        }
      }
    }
  ],
  "_linked": {}
}

If you create a HTTP Request using PUT method to child's URL you will never affect the parent, and the opposite is also true. Usually, inherited media types should have a non-nullable property MIB_PARENT_ID that points to original entity, and when you POST to an extension table you must always inform this property, in order to link the entity with its parent.


17 - Upserting an entity

Through a HTTP PUT request you can upsert a record in the MibServer. Upsert may Insert a new entity or Update an existing entity. The taken action is chosen depending on which field(s) is(are) defined at the query string. Those fields will be used to identify existent entities in the database. If the entity already exists, it will be updated. Otherwise, it will be inserted.

For example: Given the field NAME as the identifier field, current persisted entities will be searched using the NAME of the entity that is being upserted.

This is a synchronous operation and result in a HTTP 40x code with an error message or in a HTTP 201 Created message when success, with the new or already existent ID. Not all fields are required, except all fields set as identifier fields and the entity must be sent through the body of the request.

PUT /api/v1/mvp_genres?fields=NAME HTTP/1.1

Host: mediaibox.mydomain.com

Authorization: Bearer mYs3cr3tT0k3n

Accept: application/vnd.api+json

Content-Type: application/vnd.api+json;charset=UTF-8

{

"mvp_genres":[

  {

     "name":"Policial",

     "owner":"1",

     "CONTENT_SELECTION_ID":"1"

  }

]

}

In case of update, successful response:

HTTP/1.1 201 Created

Location: /api/v1/mvp_genres/3082

ETag: "r0Wv3r$10n1"

Content-Type: application/vnd.api+json;charset=UTF-8

{

"_meta": {

    "_pageCount": 1,

    "_filterRowCount": 1,

    "_pageSize": 20,

    "_previousPage": "",

    "_nextPage": "",

    "_mainMediaType": "mvp_genres",

    "_ids": [

        3082

    ],

    "_childMediaType": null,

    "_include": [],

    "_childInclude": null,

    "_sortOrder": {},

    "_fields": {},

    "_filter": {

        "_root": {

            "operator": "and",

            "children": []

        }

    },

    "_sourcePermission": {

        "write": "none",

        "delete": "none"

    },

    "_page": 0,

    "_displayValuePattern": {},

    "_hideMeta": false,

    "_hideLinks": false,

    "contentSelection": null

},

"_links": {

    "mvp_genres.content_selection_id": {

        "_href": "/api/v1/content_selection/{mvp_genres.content_selection_id}",

        "_type": "content_selection"

    },

    "mvp_genres.mvp_movies": {

        "_href": "/api/v1/mvp_genres/{mvp_genres.id}/mvp_movies",

        "_type": "mvp_movies"

    }

},

"mvp_genres": [

    {

        "_id": 3082,

        "_href": "/api/v1/mvp_genres/3082",

        "_type": "mvp_genres",

        "_etag": "4u6daa5Y8F07usk4hf0NPw",

        "_displayValue": "Policial",

        "dateins": 1549312189,

        "name": "Policial",

        "owner": 1,

        "_permissions": {

            "can_write": true,

            "can_delete": true,

            "can_read": true

        },

        "_links": {

            "content_selection_id": {

                "operation": "Add",

                "values": 1

            }

        }

    }

],

"_linked": {}

}

In case of insert, the response is equivalent, but the id corresponds to the newly persisted entity.

A 403 Forbidden may be returned if there is any problem with the request body, such as: More than one entity per request, or no entity in request; so you want to treat this exception.

HTTP/1.1 403 Forbidden

Content-Type: application/vnd.api+json

{

"error": "request_invalidjsondocument",

"error_message": "[Request/InvalidJsonDocument]",

"more_info": "Only one entity may be upserted."

}

A 400 Bad Request may be returned if there is any problem related to the identifier field(s), such as: there is no identifier field set, or more than one entity was found due to the field set as an identifier; so you want to treat this exception.

HTTP/1.1 400 Bad Request

Content-Type: application/vnd.api+json

{

"error": "request_invalidfilter",

"error_message": "[Request/InvalidFilter]",

"more_info": "More than one registers were found with the given combination of Fields and Values. Please provide a set of Fields able to identify registries properly."

}

For multiple upserts, the user may send multiple upsert requests via batch.

18 - HTTP Responses

200 → OK, body with data.

201 → OK, inserted, no body. Header 'Location' with /MediaType/newId.

204 → OK, there's no need for a response body.

206 → OK, but is a Partial Content (Resumable upload).

304 → ETag not modified, your version is still valid.

400 → Validation error, body contains details.

401 → Invalid session token, please renew it.

403 → User has no access to this MediaType.

404 → ID not found (get by ID, update or delete).

Attention: as of MIB v5.0.x, when the method /<MediaType>/<ID> is called with an invalid id, the API still responds with status code 200, and an empty entity. This is being kept this way for backwards compatibility reasons with the rest of the MIB CMS components, and will be revised in the future. Temporarilly, to allow other APIs to get the correct response, a flag was introduced. You can read about it (and how to use) here.

409 → Conflict (can't change object because it's not in the same version as expected).

Code GET (single) GET (list) PUT (update) POST (insert) DELETE
200 Success Success
201 Success
204 Empty result Success Success
206 Partial Content
304 Not modified
400 Malformed query Validation error Validation error
401 Invalid token Invalid token Invalid token Invalid token Invalid token
403 No permission No permission No permission No permission No permission
404 Not found Invalid ID Invalid MediaType Invalid ID
409 Version conflict Version conflict

19 - Internal Operations


19.1 - DRM

To save drm keys of a media a route was created to be used internally by the upload agent. It receives as parameter an array of _drmDataContainer. The fields that may be passed are Name, Owner, Mediatype, Content_Id, Content_Key, Key_Id and Drm_Type.

POST /api/v1/drmkeydata HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
"_drmDataContainer": [
            {
                  "_name": null,
                  "_owner": 0,
                  "_mediaType": 17,
                  "_contentId": 13,
                  "_keyId": "assetId-value"
                  "_drmType": 8
            },
            {
                  "_name": null,
                  "_owner": 0,
                  "_mediaType": 17,
                  "_contentId": 13,
                  "_keyId": "KeyIdTest",
                  "_contentKey": "contentKeyTest",
                  "_drmType": 32
            },
            {
                  "_name": null,
                  "_owner": 0,
                  "_mediaType": 17,
                  "_contentId": 13,
                  "_keyId": "drmkeyid-valueTest",
                  "_contentKey": "drmseed-valueTest",
                  "_drmType": 2
            }
      ]

As can be seen in the request, the fields Name, Owner and Content_Key are not mandatory but Mediatype, ContentId, KeyId and DrmType are.

The name field, even with value passed, will be replaced by a string which is the combination of the field values Mediatype ContentId, drmKey.KeyId, DrmType;Ex: "17-13-assetId-value-8".


20 - Other


20.1 - Flag for correct status code on invalid get /<MediaType>/<ID>

Although the documentation lists 404 as the expected status code for invalid GET of an inexistent /<MediaType>/<ID>, the API always responded with 200, and the body containing the META for the MediaType, but an empty array of entities.

This is something that will be revised and fixed on a future release, but as of MIB v5.0.x this was not changed to minimize the risks of problems, as all the parts of the CMS do expect this type of response and treat them correctly.

To allow for other APIs/services to get the correct response (404), a flag (X-MEDIAIBOX-ENABLE-ERROR-CODE=true) was introduced in MIB v5.0.23, which can be set on the header.

Request:

GET /api/v1/mvp_genres_metadatas/3 HTTP/1.1
Host: mediaibox.mydomain.com
Authorization: Bearer mYs3cr3tT0k3n
If-None-Match: "r0Wv3r$10n0"
Accept: application/vnd.api+json
X-MEDIAIBOX-ENABLE-ERROR-CODE: true

Response:

HTTP/1.1 404 Not Found