12

## Vendor MIME PHP >= 5.4

versioning mime mediatype vendor custom

This example shows how to use vendor specific media types for versioning

### Vendor-Specific Media Types

> Media types use the subtype prefix `vnd` to indicate that they are owned and controlled by a `vendor`. Vendor-specific media types convey a clear description of a message's content to the programs that understand their meaning. - REST API Design Rulebook

Important steps are

    Defaults::$apiVendor = "SomeVendor";
    Defaults::$useVendorMIMEVersioning = true;

    $r = new Restler();
    $r->setAPIVersion(2);
    //...

> This API Server is made using the following php files/folders

> - index.php (gateway)
> - v1\BMI.php (api)
> - v2\BMI.php (api)
> - Resources.php (api)
> - restler.php (framework)
> - JsonFormat.php (format)

This API Server exposes the following URIs

    GET bmi                    ⇠ SomeVendor\v2\BMI::index()
    GET resources              ⇠ Luracast\Restler\Resources::index()
    GET resources/verifyaccess ⇠ Luracast\Restler\Resources::verifyAccess()
    GET resources/{id}         ⇠ Luracast\Restler\Resources::get()

Here is how you will consume different versions of the api using cURL.

Version 1

    curl 'http://restler3.luracast.com/examples/_012_vendor_mime/index.php/bmi?height=162.6&weight=84' -H 'Accept: application/vnd.somevendor-v1+json' -i

    HTTP/1.1 200 OK
    Date: Sun, 06 Jan 2013 10:46:40 GMT
    Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.14 mod_ssl/2.2.22 OpenSSL/0.9.8o
    X-Powered-By: Luracast Restler v3.0.0rc3
    Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
    Vary: Accept
    Cache-Control: no-cache, must-revalidate
    Expires: 0
    Content-Language: en
    Content-Length: 209
    Content-Type: application/vnd.SomeVendor-v1+json; charset=utf-8

    {
      "bmi": 31.77,
      "message": "Obesity",
      "metric": {
        "height": "162.6 centimeters",
        "weight": "84 kilograms"
      },
      "imperial": {
        "height": "5 feet 4 inches",
        "weight": "185.19 pounds"
      }
    }

Version 2 without unit

    curl 'http://restler3.luracast.com/examples/_012_vendor_mime/index.php/bmi?height=162.6&weight=84' -H 'Accept: application/vnd.somevendor-v2+json' -i

    HTTP/1.1 400 Bad Request
    Date: Sun, 06 Jan 2013 10:48:19 GMT
    Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.14 mod_ssl/2.2.22 OpenSSL/0.9.8o
    X-Powered-By: Luracast Restler v3.0.0rc3
    Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
    Vary: Accept
    Cache-Control: no-cache, must-revalidate
    Expires: 0
    Content-Language: en
    Content-Length: 87
    Connection: close
    Content-Type: application/vnd.SomeVendor-v2+json; charset=utf-8

    {
      "error": {
        "code": 400,
        "message": "Bad Request: invalid height unit"
      }
    }

Version 2 with unit

    curl 'http://restler3.luracast.com/examples/_012_vendor_mime/index.php/bmi?height=1.626meters&weight=84kilograms' -H 'Accept: application/vnd.somevendor-v2+json' -i

    HTTP/1.1 200 OK
    Date: Sun, 06 Jan 2013 11:05:26 GMT
    Server: Apache/2.2.22 (Unix) DAV/2 PHP/5.3.14 mod_ssl/2.2.22 OpenSSL/0.9.8o
    X-Powered-By: Luracast Restler v3.0.0rc3
    Set-Cookie: ZDEDebuggerPresent=php,phtml,php3; path=/
    Vary: Accept
    Cache-Control: no-cache, must-revalidate
    Expires: 0
    Content-Language: en
    Content-Length: 209
    Content-Type: application/vnd.SomeVendor-v2+json; charset=utf-8

    {
      "bmi": 31.77,
      "message": "Obesity",
      "metric": {
        "height": "162.6 centimeters",
        "weight": "84 kilograms"
      },
      "imperial": {
        "height": "5 feet 4 inches",
        "weight": "185.19 pounds"
      }
    }

We expect the following behaviour from this example.

    @example12 @versioning
    Feature: Testing Versioning with vendor MIME

      Scenario: Access version 1 by vendor media type
        Given that "Accept" header is set to "application/vnd.SomeVendor-v1+json"
        When I request "examples/_012_vendor_mime/bmi?height=190"
        Then the response status code should be 200
        And the response "Content-Type" header should be "application/vnd.SomeVendor-v1+json; charset=utf-8"
        And the response is JSON
        And the type is "array"
        And the response has a "bmi" property
        And the "message" property equals "Normal weight"
        And the "metric.height" property equals "190 centimeters"

      Scenario: Access version 2 by vendor media type and passing invalid argument
        Given that "Accept" header is set to "application/vnd.SomeVendor-v2+json"
        When I request "examples/_012_vendor_mime/bmi?height=190"
        Then the response status code should be 400
        And the response "Content-Type" header should be "application/vnd.SomeVendor-v2+json; charset=utf-8"
        And the response is JSON
        And the type is "array"
        And the "error.message" property equals "Bad Request: invalid height unit"

      Scenario: Access version 2 by vendor media type
        Given that "Accept" header is set to "application/vnd.SomeVendor-v2+json"
        When I request "examples/_012_vendor_mime/bmi?height=190cm"
        Then the response status code should be 200
        And the response "Content-Type" header should be "application/vnd.SomeVendor-v2+json; charset=utf-8"
        And the response is JSON
        And the type is "array"
        And the response has a "bmi" property
        And the "message" property equals "Normal weight"
        And the "metric.height" property equals "190 centimeters"

It can be tested by running the following command on terminal/command line from the project root (where the vendor folder resides). Make sure `base_url` in `behat.yml` is updated according to your web server.

    vendor/bin/behat  features/examples/_012_vendor_mime.feature