Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<a name="4.2.0"></a>
# [4.2.0](https://github.com/mulesoft/api-console/compare/v4.1.0...v4.2.0) (2017-10-25)

- Changed behavior of the `baseUri` property as described in [#535](https://github.com/mulesoft/api-console/issues/535)
- Added this changelog
- Many bug fixes in the internal web components

# [4.1.0](https://github.com/mulesoft/api-console/compare/v4.0.0...v4.1.0) (2017-08-17)

- New: Support for sending files
- New: Added demo page for adding distributed content into the console.
- New: Added demo page for selecting an API version inside the console.
- New: Added `noAttribution` option. Attribution is now part of the console instead of the builder.
- Update: redesign of the "body" editor in the request editor
- Fix: Console is not completing the path whit host and port when Base URI set relative #502
- Fix: Title of the API is not fully displayed #519
- Fix: Add ability to add custom content to the console element as a distributed child #520
- Fix: How to enter application/x-www-form-urlencoded for a post body? #374
- Fix: No feedback for file type #199
- Update: Updated demo pages of the console. See `demo` folder for more information
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
**See live example of the API console in our [demo application].**

# The API Console

MuleSoft's API Console is a full-fledged API documentation tool that generates mobile-friendly web documentation based on RAML (Restful API Modeling Language) documents. In addition to providing documentation, the tool provides the capability for users to try out requests on the fly.

[![API Console](docs/new-console-header.png)](https://mulesoft.github.io/api-console)

**See live example of the API console in our [demo application].**

## Introduction

In this repository, you can find the source for a single HTML element that represents API Console.
Expand All @@ -16,6 +16,26 @@ The following sections briefly describe how to build and use the console. For mo

## Using the API console

Install our CLI tool globally using `-g` if possible:

```shell
$ sudo npm install -g api-console-cli
```

Generate API console from your RAML file:

```shell
$ api-console build https://domain.com/api.raml # works with local files too
```

Preview the console:

```shell
$ api-console serve build/
```

That's all you need to build the API console for your API. Below we'll describe how to customize the console.

API Console comes in two flavors.

* A **standalone web-application**
Expand Down
9 changes: 3 additions & 6 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"authors": [
"The Advanced REST client authors <arc@mulesoft.com>"
],
"version": "4.1.0",
"version": "4.2.0",
"keywords": [
"web-components",
"polymer",
Expand All @@ -30,7 +30,7 @@
"paper-icon-button": "PolymerElements/paper-icon-button#~1.1.0",
"raml-aware": "advanced-rest-client/raml-aware#^1.0.2",
"paper-toast": "PolymerElements/paper-toast#^1.3.0",
"raml-request-panel": "advanced-rest-client/raml-request-panel#^0.2.1",
"raml-request-panel": "advanced-rest-client/raml-request-panel#^0.3.2",
"raml-documentation-panel": "advanced-rest-client/raml-documentation-panel#^2.0.9",
"paper-progress": "PolymerElements/paper-progress#^1.0.11",
"paper-button": "PolymerElements/paper-button#^1.0.14",
Expand Down Expand Up @@ -71,8 +71,5 @@
"tasks",
"demo",
"docs"
],
"resolutions": {
"payload-parser-behavior": "0.2.1"
}
]
}
17 changes: 9 additions & 8 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# API Console documentation

Select a topic
- [API Console element documentation](api-console-element.md)
- [API Console build tools](build-tools.md)
- [API Console configuration options](configuring-api-console.md)
- [Building API Console for GitHub pages on Travis](gh-pages.md)
- [Handling CORS](cors.md)
- [Passing RAML to the API Console](passing-raml-data.md)
- [Rebuilding the api.json file in the CI process](rebuilding-api-json.md)
- [Styling the API Console](theming.md)
- [Starting guide to web components](web-components.md)
- [API Console element documentation](api-console-element.md)
- [API Console build tools](build-tools.md)
- [API Console configuration options](configuring-api-console.md)
- [Building API Console for GitHub pages on Travis](gh-pages.md)
- [Handling CORS](cors.md)
- [Passing RAML to the API Console](passing-raml-data.md)
- [Rebuilding the api.json file in the CI process](rebuilding-api-json.md)
- [Styling the API Console](theming.md)
4 changes: 3 additions & 1 deletion docs/configuring-api-console.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ The following table describes HTML attributes.
| `manual-navigation` | Disables navigation in the drawer and renders the navigation full screen when requested. Use in the narrow layouts with the `narrow` property. Set the `navigationOpened` property to `true` or `false` to open/close the navigation. | `Boolean` |
| `navigation-opened` | If set, the `manual-navigation` attribute is set, and the full screen navigation will open/close. | `Boolean` |
| `bower-location` | If the path to the `bower_components` is different than default (in the root path) then set this attribute to point the location of the folder, including folder name. | `String` |
| `no-url-editor` | If set, the URL editor is hidden in the Try it panel. The editor is still attached to the DOM but it's invisible to the user. | `Boolean`
| `no-url-editor` | If set, the URL editor is hidden in the Try it panel. The editor is still attached to the DOM but it's invisible to the user. | `Boolean` |
| `base-uri` | Used to replace RAML's base URI. Once set it updates the request URL in the request panel (try it). The URL will always contain the same base URL until the attribute is cleared (removed, set to `null`, `undefined` or `false`) | `String`


## Controlling the view

Expand Down
163 changes: 103 additions & 60 deletions docs/passing-raml-data.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,108 @@
# Passing the RAML data

## Before you begin: asynchronous environment
The default version of the **API console does not contain the RAML parser**. It is by design to minimize the size of the console and to optimize startup time.

Web components are asynchronous by nature. Importing the elements,
registering them in the DOM, and finally initializing an element is done asynchronously. Therefore, you can't expect the element to work immediately after loading the page as a typical HTML element does. Consider the following example:
You can use the console with the RAML parser by setting up the build / CLI tools or by adding the dependency manually. **This document describes why the parser has been removed from the core console code and how to use the parser with new console.**

```html
<link rel="import" href="bower_components/raml-js-parser/raml-js-parser.html">
<raml-js-parser json></raml-js-parser>
<script>
var parser = document.querySelector('raml-js-parser');
parser.loadApi(apiFileUrl);
</script>
```
## Performance of the API console

Running this code as the page loads throws a `TypeError` with the message: `parser.loadApi is not a function`.
One of the challenges standing before us when we started developing version 4 of the API console was the performance. This is wide area so here we'll limit it to size of the source code and initial start time.

At the time of execution of this script block, the browser knows nothing about the `raml-js-parser` element. At this time, the element is an instance of `HTMLUnknownElement`.
Before we go into detailed performance issues description read why we use the enhancer alongside the JS parser.

The browser has to import the source of the element first, and then the Polymer library has to register custom HTML element called `raml-js-parser`.

To run the code properly you have to listen for the `WebComponentsReady` event. It's fired when the elements are ready to use.
### RAML <> JavaScript enhancer

As you may already know the API console consists of over 150 web components. They are responsible for displaying the documentation, rendering the request and response panels in the "try it" function and to make test requests to an endpoint.

[RAML's JavaScript parser][5] has been created to give access to RAML document's [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree). It is very inconvenient to use it with HTML templating systems (like Polymer's or Angular's). The parser simply hasn't been created for this use case. Apart from offering the AST the parser produces a JavaScript object. The object can be used in many cases in JavaScript environment. However the output is not as helpful in the world of web components.

The components serves one purpose and are responsible for a single task in the API console. For example there is an element that renders annotation added to a type only. Because of that not every element need to have access to full RAML description. It only uses part of the documentation that it is going to use. Parser's JavaScript output gives literally translated YAML structure to a JavaScript object. It means that if you, for example, declare a type on a `body` declaration as a name of previously defined type on the root of the RAML document, the parser's output is this name and not the type definition. Therefore parser JavaScript output requires additional transformations before it can be used with web components architecture.

For the API Console we use our fork of the [raml2obj][11] library as a base transformer. With the [expansion library][12] we've created an web component [raml-json-enhance][3] and node module [raml-json-enhance-node][4] that transforms parser's output to a form that can be used with the components of the API console.

Output of the enhancer is then to be used as an input data of the API console. Use of the enhancer also allowed us to minimize code base of all the web components because they don't need to contain code to compute missing properties.

### Console source size

The first issue is the size of the console. When you install dependencies of the console it turns out that the whole project is about 40MB (excluding `node_modules`). That's a lot but this is a development version of the console.
We have prepared a [build tools][1] for the console, that works on top of Polymer's [build tools][1] to produce production ready version of the console. With optimization option enabled (default behavior) it produces a single file with all web components definitions concatenated to a single 2MB file. It is still quite a lot but so far we were able to reduce the code to this size.

### Console startup time

Big issue for the API console in version < 4.0.0 was startup time. Each time the console was loaded into the browser it had to download all RAML sources, parse it and then render the console based on JavaScript parser output. In many cases two first steps are simply redundant. If the API specification doesn't change very often there's no reason to parse the RAML each time the console is opened. We've replaced this part with prebuilt of the parser's output file that contains transformed RMAL data. In case of huge and complicated APIs it can significantly reduce startup time.

Separation of the data source and the API console has additional advantage. In new architecture, when source RAML changes you can just rebuild the JSON file with new data instead of rebuilding the console. This speeds up publish time of new API an can be easily automated in your [CI pipeline][10].

Our [build tools][1] gives you options to include the parser and enhancer to the final build so, depending on your use case, you can optimize startup time of the console.

## Installing parser and enhancer

You can install parser and enhancer in your project by calling [bower][9] command:

```html
<link rel="import" href="bower_components/raml-js-parser/raml-js-parser.html">
<raml-js-parser json></raml-js-parser>
<script>
function init() {
var parser = document.querySelector('raml-js-parser');
parser.loadApi(apiFileUrl);
};
window.addEventListener('WebComponentsReady', init);
</script>
```
$ bower install --save advanced-rest-client/raml-json-enhance advanced-rest-client/raml-js-parser
```

## JSON instead of RAML
You can use `package.json` script declaration for the same command:

The API console web component requires a JavaScript object produced by the [raml-js-parser] and [raml-js-enhance] elements. Parsing and enhancing RAML is not part of the `api-console` element and must be performed separately as described below.
```json
"scripts": {
"install-parser": "bower install --save advanced-rest-client/raml-json-enhance advanced-rest-client/raml-js-parser"
}
```
```
$ npm run install-parser
```

**Head's up!** You can use our [build tools] to generate the JSON file from the RAML in Node (using node modules) and Shell (with the API Console CLI tool).
Or in combination with installation of the console:

Use the [raml-js-parser] element to parse YAML data or to download RAML from a remote location. __Note__: You may also use our [raml-js-parser-2] node library as it yields the same output.
```
$ bower install --save mulesoft/api-console advanced-rest-client/raml-json-enhance advanced-rest-client/raml-js-parser
```

Then, you **must** use the [raml-js-enhance] element to produce data output that is recognizable by the `api-console`. The enhancer creates a common data structure and expands RAML types by flattening any type having a complex inheritance structure.
It installs source files in `bower_components` directory. You can then reference those files in the `import` directive. After the components are imported and registered you can use them as described in our [web components guide][2].

Elements used to build API Console expect the JSON object to contain complete data about a method / endpoint / type / security scheme and so on. They do not look into nor have access to the data in the root of RAML definition. The enhancer replaces objects with arrays, adding a `key` property to each item, for use in a templating system. Also, the `example` property of the RAML is always translated to an `examples` array. Finally, the enhancer creates a `fullUrl` property on each HTTP method so the console doesn't need to compute it each time you open the documentation page.
Also check out our usage guide of the `<api-console>` element in our [element's guide][8].

#### Example: parsing and enhancing RAML
### Example use of parser and enhancer

```html
<link rel="import" href="bower_components/raml-js-parser/raml-js-parser.html">
<link rel="import" href="bower_components/raml-json-enhance/raml-json-enhance.html">
<link rel="import" href="bower_components/api-console/api-console.html">

<raml-js-parser json></raml-js-parser>
<raml-json-enhance></raml-json-enhance>
<api-console></api-console>

<script>
var parser = document.querySelector('raml-js-parser');
parser.addEventListener('api-parse-ready', function(e) {
var enhacer = document.querySelector('raml-json-enhance');
enhacer.json = e.detail.json.specification;
});
window.addEventListener('raml-json-enhance-ready', function(e) {
// The e.detail.json contains the final JavaScript object
console.log(e.detail.json);
});
function init() {
parser.loadApi(apiFileUrl);
var MyAPiApp = {
init: function() {
var parser = document.querySelector('raml-js-parser');
parser.addEventListener('api-parse-ready', MyAPiApp._ramlReady);
parser.loadApi('https://domain.com/api.raml');
window.addEventListener('raml-json-enhance-ready', MyAPiApp._jsonReady);
},

_ramlReady: function(e) {
var enhacer = document.querySelector('raml-json-enhance');
enhacer.json = e.detail.json.specification;
},

_jsonReady: function(e) {
// The e.detail.json contains the final JavaScript object
var apiConsole = document.querySelector('api-console');
apiConsole.raml = e.detail.json;
}
};
window.addEventListener('WebComponentsReady', init);
window.addEventListener('WebComponentsReady', MyAPiApp.init);
</script>
```

1) After the elements are initialized, the`WebComponentsReady` event occurs and calls the `loadApi()` function on the [raml-js-parser] element.
2) The element fires the `api-parse-ready` custom event that should be handled by the application and the result of parsing (`e.detail.json.specification`) should be passed to the enhancer's `json` property.
3) When the enhancer transforms the object, it fires the `raml-json-enhance-ready` custom event. The result is in the `e.detail.json` property.
The `json` attribute set on `raml-js-parser` element tells the parser that the output should be a JavaScript object instead of the AST.

Parsing and enhancing can consumes significant system resources, depending on the RAML structure and number of referenced files. It is a good idea to do perform these operations once and cache the results. Then, when the user visits the page again, restore the cached JSON object, and pass it as the `api-console` parameter as discussed below.

### Setting RAML data as an HTML attribute
### Setting RAML data as a HTML attribute

The basic method for determining what API Console displays is to use the `raml` attribute. The attribute accepts the JavaScript object produced by the parser and the enhancer described above.

Expand All @@ -96,19 +124,28 @@ The `<api-console>` element also has a convenient `json-file` attribute that can
<api-console json-file="api.json"></api-console>
```

This method is the most flexible method of passing the RAML data. You can use our [build tools] to regenerate the `api.json` file in your CI process automatically as soon as you publish changes in your API.
This method is the most flexible method of passing the RAML data. You can use our [build tools][1] to regenerate the `api.json` file in your CI process automatically as soon as you publish changes in your API.

### Using RAML aware to pass the data

API console internally uses the [raml-aware] element.
API console internally uses the [raml-aware][6] element.
This element can be used to pass the RAML data to the console if direct access to the
element is not possible, for example, if the console is encapsulated in the [shadow DOM].
element is not possible, for example, if the console is encapsulated in the [shadow DOM][7].

See the [raml-aware][6] documentation page for more information.

#### Install

See the [raml-aware] documentation page for more information.
```
$ bower install --save advanced-rest-client/raml-aware
```

#### Example

```html
<link rel="import" href="bower_components/raml-aware/raml-aware.html">
<link rel="import" href="bower_components/api-console/api-console.html">

<raml-aware scope="main-raml"></raml-aware>
<api-console aware="main-raml"></api-console>
```
Expand All @@ -121,9 +158,15 @@ window.addEventListener('raml-json-enhance-ready', function(e) {
parser.loadApi(urlToApi);
```

[build tools]: docs/build-tools.md
[raml-js-enhance]: https://elements.advancedrestclient.com/elements/raml-json-enhance
[raml-js-parser]: https://elements.advancedrestclient.com/elements/raml-js-parser
[raml-js-parser-2]: https://github.com/raml-org/raml-js-parser-2
[raml-aware]: https://elements.advancedrestclient.com/elements/raml-aware
[shadow DOM]: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM
[1]: build-tools.md
[2]: web-components.md
[3]: https://elements.advancedrestclient.com/elements/raml-json-enhance
[4]: https://elements.advancedrestclient.com/elements/raml-json-enhance-node
[5]: https://github.com/raml-org/raml-js-parser-2
[6]: https://elements.advancedrestclient.com/elements/raml-aware
[7]: https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM
[8]: api-console-element.html
[9]: https://bower.io
[10]: rebuilding-api-json.md
[11]: https://github.com/advanced-rest-client/raml2obj
[12]: https://github.com/raml-org/datatype-expansion/
Loading