Nav

How to Design an API

In this quickstart, we focus on designing a REST API by writing a RAML definition to match an example SOAP service’s WSDL.

Prerequisites

To create an API in Anypoint Platform, you need the following:

  • Anypoint Platform account. If you do not have an account, click Sign up.

  • API Creators and/or Organization Administrator Access. After you log into Anypoint Platform, click Access Management from either the left navigation bar or the starting screen.

    You can press the Escape key on your keyboard to open or close the left navigation bar in Anypoint Platform.

    In the Access Management screen, click Roles and look for API Creators or Organization Administrator. If one or both of these roles are visible in the Roles listing, you can proceed with this quickstart. If you cannot see these roles, contact your site’s administrator before proceeding with this quickstart.

    API Roles

Create an API Definition

An API definition is the name of an API and its version that you specify in the API Manager.

After signing in to Anypoint Platform, follow these steps to create an API:

  1. From the Anypoint Platform main screen or left navigation bar, click API Manager. The API administration page appears, listing the names of APIs, if there are any, that you are authorized to see.

  2. Click Add new API.

    The Add API dialog appears.

    add-api

  3. Enter the following required information:

    • API name: T-Shirt Ordering Service

    • Version name: 1.0.development

    • API endpoint: Leave blank for now

    • Description: Order the best T-Shirts for all occasions.

  4. Click Add.

    The T-Shirt Ordering Service appears that includes the API Definition, which you use in the next step.

    api-definition

Build a RAML File for an Existing API

For this example, we convert an existing WSDL SOAP Service definition to REST. While the WSDL file may appear undecipherable by viewing it, the table below provides the key information that we use to replace the WSDL with a REST interface using the RESTful API Modeling Language (RAML).

The WSDL for the T-shirt API lists these set of operations:

Operation Assigned SOAP resource

Show all inventory

ListInventory

Place a T-Shirt order

OrderTshirt

Track an existing T-Shirt order

TrackOrder

We need to create resources in the RAML to match the operations in the WSDL:

Operation Assigned SOAP resource RAML resource

Show all inventory

ListInventory

products

Place a T-Shirt order

OrderTshirt

orders

Track an existing T-Shirt order

TrackOrder

status

Define the API in the API Designer

In this section, we define the logic of the API using RAML. Anypoint Platform provides the API Designer, which is a RAML editor. API Designer helps you design an API in the following ways:

  • Checks and highlights syntax

  • Provides instant feedback, flagging incorrect syntax

  • Displays a shelf of clickable hints for inserting the next line of code

  • Includes a mocking service - The mocking service lets you test your API with simulated data.

To define a REST API in API Designer:

  1. Locate the API Definition for the T-Shirt Ordering Service.

    api-definition

  2. Click Define API in API designer.

    API Designer appears and generates the first few lines of RAML based on the information you entered, which provides the required declaration of the RAML version, and the title and version of the API.

    #%RAML 1.0
    title: T-Shirt Ordering Service
    version: 1.0.development

    The shelf of clickable hints about valid operations appears at the bottom of API Designer.

  3. Click shelf-icon to expand the shelf if necessary.

    api-designer-shelf

  4. Click baseUri on the API Designer shelf.

    A placeholder, http://server/api{version} for a baseUri appears on the next line. The web site that incorporates the database logic and user interface for the web service does not yet exist, so you use a placeholder.

  5. Remove {version} from the placeholder baseUri: http://server/api

  6. Include the resources in the RAML, formatting each resource as URI relative to the baseUri.

    For this example, the resources are:

    • Products, T-shirts

    • Orders

    Use a forward slash followed by an arbitrary resource name and a colon to enter resources in URI format, as shown in the following example:

    ...
    baseUri: http://server/api
    /products:
    /orders:
  7. Enter the methods associated with the resources, indenting the method name followed by a colon on the line below the resource names:

    • Enter the GET method below the /products resource.

      Call this method to get information about products.

    • Enter the POST method below the /orders resource.

      Call this method to place new orders for t-shirts.

      ...
      baseUri: http://server/api
      /products:
        get:
      /orders:
        post:
  8. Below each method, include an indented description followed by responses. Responses consist of a map of the HTTP status codes that the API returns on success. The descriptions, responses, and examples are:

    ...
    /products:
      displayName: products
      get:
        description: Gets a list of all the inventory products
        responses:
          200:
            body:
              application/json:
                example: |
                  [
                    {
                      "productCode": "TS",
                      "size": "S",
                      "description": "Small T-shirt",
                      "count": 30
                    },
                    {
                      "productCode": "TS",
                      "size": "M",
                      "description": "Medium T-shirt",
                      "count": 22
                    }
                  ]
    /orders:
      displayName: orders
      post:
        description: Places a new T-Shirt order

Use the Mocking Service

The mocking service simulates calls to the API methods and returns results from the examples you included in the RAML. In this procedure, you exercise a GET request using the mocking service.

To use the mocking service:

  1. Above the API console on the right, turn on the Mocking Service.

    API Designer comments out the baseUri that you entered and inserts a mocking service Uri.

    The Resources mockup has a GET and a POST tab.

  2. On the GET tab, click Try It, and then click GET.

    The following examples appear in Body:

    [
      {
        "productCode": "TS",
        "size": "S",
        "description": "Small T-shirt",
        "count": 30
      },
      {
        "productCode": "TS",
        "size": "M",
        "description": "Medium T-shirt",
        "count": 22
      }
    ]

Complement the T-Shirt API

The procedure in this section adds the following things:

  • A schema

  • A status resource

  • Query parameters for querying the status resource using the requester email and the order ID.

To ensure that POST requests sent to the /orders resource are valid, enforce a structure by using a schema. The schema and incoming requests are compared. A match ensures validity.

  1. Add a schema.

    ...
    /orders:
      ...
              }
            schema: |
              {
                "type": "object",
                "$schema": "http://json-schema.org/draft-04/schema",
                "id": "http://jsonschema.net",
                "required": true,
                "properties": {
                  "address1": {
                      "type": "string",
                      "id": "http://jsonschema.net/address1",
                      "required": true
                  },
                  "address2": {
                      "type": "string",
                      "id": "http://jsonschema.net/address2",
                      "required": true
                  },
                  "city": {
                      "type": "string",
                      "id": "http://jsonschema.net/city",
                      "required": true
                  },
                  "country": {
                      "type": "string",
                      "id": "http://jsonschema.net/country",
                      "required": true
                  },
                  "email": {
                      "type": "string",
                      "format": "email",
                      "id": "http://jsonschema.net/email",
                      "required": true
                  },
                  "name": {
                      "type": "string",
                      "id": "http://jsonschema.net/name",
                      "required": true
                  },
                  "size": {
                      "type": "string",
                      "enum": ["S", "M", "L", "XL", "XXL"],
                      "id": "http://jsonschema.net/size",
                      "required": true
                  },
                  "stateOrProvince": {
                      "type": "string",
                      "id": "http://jsonschema.net/stateOrProvince",
                      "required": true
                  },
                  "postalCode": {
                    "type": "string",
                    "id": "http://jsonschema.net/postalCode",
                    "required": true
                  }
                }
              }

    Below the schema, add the /status resource:

    ...
    /status:
      displayName: Status
      get:
        responses:
          200:
            body:
              application/json:
                example: |
                  {
                    "orderId": "4321",
                    "status": "Delivered",
                    "size": "M"
                  }
  2. At the same level on the tree structure as the operation responses label, add a queryParameters element to the GET operation with the following attributes:

    
                
             
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
          queryParameters:
            orderId:
              description: Provide a valid order Id.
              required: true
              type: integer
              example: "4321"
            email:
              description: Provide a valid email address.
              pattern: ^[_a-z0-9-]+(\.[_a-z0-9-]+)*@mule.com
              required: true
              example: "max@mule.com"

Before finishing, remember to change the default api.raml file name for a more descriptive one.
To do this, click the gear icon next to the raml file name, and select Rename:

design-an-api-4485se

Name this API description file as t-shirt.raml

The resulting RAML should look like this:


         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#%RAML 1.0
title: T-Shirt Ordering Service
version: 1.0.development
baseUri: http://server/api/
/products:
  displayName: Products
  get:
    description: Get a list of all the inventory products
    responses:
      200:
        body:
          application/json:
            example: |
              [
                {
                  "productCode": "TS",
                  "size": "S",
                  "description": "Small T-shirt",
                  "count": 30
                },
                {
                  "productCode": "TS",
                  "size": "M",
                  "description": "Medium T-shirt",
                  "count": 22
                }
              ]
/orders:
  post:
    description: Places a new T-Shirt order
    body:
      application/json:
        example: |
          {
            "size": "M",
            "email": "robin@mail.com",
            "name": "Robin Pille",
            "address1": "77 Geary St.",
            "address2": "Apt 7",
            "city": "San Francisco",
            "stateOrProvince": "CA",
            "country": "US",
            "postalCode": "94131"
          }
        schema: |
          {
            "type": "object",
            "$schema": "http://json-schema.org/draft-03/schema",
            "id": "http://jsonschema.net",
            "required": true,
            "properties": {
              "address1": {
                  "type": "string",
                  "id": "http://jsonschema.net/address1",
                  "required": true
              },
              "address2": {
                  "type": "string",
                  "id": "http://jsonschema.net/address2",
                  "required": true
              },
              "city": {
                  "type": "string",
                  "id": "http://jsonschema.net/city",
                  "required": true
              },
              "country": {
                  "type": "string",
                  "id": "http://jsonschema.net/country",
                  "required": true
              },
              "email": {
                  "type": "string",
                  "format": "email",
                  "id": "http://jsonschema.net/email",
                  "required": true
              },
              "name": {
                  "type": "string",
                  "id": "http://jsonschema.net/name",
                  "required": true
              },
              "size": {
                  "type": "string",
                  "enum": ["S", "M", "L", "XL", "XXL"],
                  "id": "http://jsonschema.net/size",
                  "required": true
              },
              "stateOrProvince": {
                  "type": "string",
                  "id": "http://jsonschema.net/stateOrProvince",
                  "required": true
              },
              "postalCode": {
                "type": "string",
                "id": "http://jsonschema.net/postalCode",
                "required": true
              }
            }
          }
  /status:
    displayName: Status
    get:
      responses:
        200:
          body:
            application/json:
              example: |
                {
                  "orderId": "4321",
                  "status": "Delivered",
                  "size": "M"
                }
      queryParameters:
        orderId:
          description: Provide a valid order Id.
          required: true
          type: integer
          example: 4321
        email:
          description: Provide a valid email address.
          pattern: ^[_a-z0-9-]+(\.[_a-z0-9-]+)*@mule.com
          required: true
          example: "max@mule.com"