Skip to content

Commit

Permalink
115-Device Capabilities Hierarchy has been added to the side navigati…
Browse files Browse the repository at this point in the history
…on, also moved all files into the docs folder of docsify
  • Loading branch information
kmehbob committed Jan 18, 2024
1 parent b0096d5 commit dabc947
Show file tree
Hide file tree
Showing 271 changed files with 13,468 additions and 0 deletions.
Empty file added .nojekyll
Empty file.
59 changes: 59 additions & 0 deletions APIs/access-api-response.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Access API response body and headers

You can access an API response through:

- **API name** set when defining the API
- **API id** set when invoking the API

Use id instead of a name for following scenarios:

1. You're setting the API name dynamically
2. The same API is called multiple times with different inputs, e.g. when looping through data

# Basic GET example

Here, we use the API name to access the response body. In EDL, expressions are wrapped in `${}` so that Ensemble runtime evaluates the expression. In this case, the expression is referencing the API response body.

```yaml
View:
onLoad:
invokeAPI:
name: getUser
body:
Column:
styles:
padding: 40
children:
- Text:
text: ${getUser.body.firstName}
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
```
# GET array of data and display using a template
An API response could include an array of objects that the app displays using an `item-template`. Any widget that supports `children` property also supports `item-template`.

```yaml
View:
onLoad:
invokeAPI:
name: getUser
body:
Column:
styles:
padding: 40
item-template:
data: ${getUser.body.users}
name: user
template:
Text:
text: ${user.firstName}
API:
getUser:
uri: https://dummyjson.com/users/
method: GET
```
30 changes: 30 additions & 0 deletions APIs/bind-item-temp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Binding APIs to Item Templates in Ensemble

When developing user interfaces, it's common to display lists of items, and Ensemble simplifies this process by providing the item-template property in the YAML syntax. This property can be assigned to container widgets like Column or Row and is particularly useful for binding API responses to data-driven UI elements.

`item-template` takes the following properties:

- `data`: This should point to an array of data.
- `name`: Set this to a value to reference in the `template`.
- `template`: This is where we define the widgets to render for each item.

| Property | Type | Description |
| -------- | ------ | ------------------------------------------------------------------------------- |
| data | string | Bind to an array of data from an API response or a variable |
| name | string | Set the name to reference as you iterate through the array of data |
| template | widget | The data row widget to render for each item, it can be a custom widget as well. |

```yaml
item-template:
data: ${getPeople2.body.results}
name: item
template:
Text:
text: ${item.name.first}
```
The `data` property of the item-template is bound to the results of the getPeople2 API call (${getPeople2.body.results}).
The `name` property is set to "item," serving as a reference to each item in the array.
The `template` property defines the structure of each item in the list. In this case, it's a Text widget displaying the first name of each person from the API response (${item.name.first}).

This setup uses the API response from getPeople2 to dynamically generate a list of Text widgets, each displaying the first name of a person from the API response.
112 changes: 112 additions & 0 deletions APIs/call-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Invoking APIs, aka calling APIs

Use `invokeAPI` action to call the APIs you defined. Here are the properties of invokeAPI:

| Property | Type | Description |
| :--------- | :----- | :------------------------------------------------------------------------- |
| id | String | Give the API an ID allows you to bind to its result. e.g. ${apiId.body...} |
| name | String | Name of the API defined in the API section |
| inputs | Object | Key value pairs ofinputs to be passed to API definition |
| onResponse | Action | The action to handle the response |
| onError | Action | The action to handle errors |


invokeAPI can be passed to any event, such as `onLoad`, `onTap`, `onPullToRefresh`, ... using EDL or code.


## invokeAPI from EDL

```yaml
View:
onLoad:
invokeAPI:
name: getUser
body:
# screen body
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
```
## invokeAPI from code (Javascript)
```yaml
View:
onLoad: |
ensemble.invokeAPI("getUser");
body:
# screen body
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
```
## Pass inputs to the API
A common interaction is to pass user provided info from a form to an API. To achieve this, set API inputs by binding to form values.
Using EDL, set `inputs` property of the `invokeAPI` action.

```yaml
View:
body:
Column:
styles:
padding: 24
gap: 8
children:
- TextInput:
id: productName
label: Product Name
- Button:
label: Submit
onTap:
invokeAPI:
name: addProduct
inputs:
productTitle: ${productName.value}
API:
addProduct:
inputs:
- productTitle
uri: https://dummyjson.com/products/add
method: POST
body:
title: ${productTitle}
```


Using code, pass `inputs` as an object.

```yaml
View:
body:
Column:
styles:
padding: 24
gap: 8
children:
- TextInput:
id: productName
label: Product Name
- Button:
label: Submit
onTap: |
ensemble.invokeAPI("addProduct", {
"productTitle": productName.value
});
API:
addProduct:
inputs:
- productTitle
uri: https://dummyjson.com/products/add
method: POST
body:
title: ${productTitle}
```
29 changes: 29 additions & 0 deletions APIs/chaining-apis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Chaining APIs

Chaining APIs, also known as making sequential API calls, is a practice in app development when you need to retrieve and use data from multiple sources in a specific order. Chaining APIs allows you to build more complex workflows and gather the necessary information for your application.

```yaml
onLoad:
- name: getuser
onResponse:
- invokeAPI:
name: getcurrentUserContacts
- invokeAPI:
name: getExtendedNetwork
- invokeAPI:
name: getinviteLink
- onResponse:
- invokeAPI:
name: getcurrentUserProperties
- onResponse:
- invokeAPI:
name: getseekingPosts
```
**Sequential API Calls:**
The onResponse event for each API call specifies the next API call to be made after the current one is successfully completed.
For example, after the initial API call named "getuser" (assuming it's defined elsewhere in your YAML), the onResponse event triggers the "getcurrentUserContacts" API call.
Similarly, the subsequent API calls ("getExtendedNetwork," "getinviteLink," "getcurrentUserProperties," and "getseekingPosts") are chained together using the onResponse events.
**Nested invokeAPI:**
The invokeAPI action is used to make API calls. Each invokeAPI action is nested within the onResponse of the previous API call, forming a chain.
75 changes: 75 additions & 0 deletions APIs/define-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Define APIs

You define APIs by adding the `API` section to any screen. Note that `API` would be at the root level of the document, i.e. as a sibling to the `View`.

```yaml
API:
myFirstApi: # a new to refer to this API later
inputs: # specify an array of inputs the API expect. You can reference the inputs in the other API properties, such as the body
uri: # the endpoint to call, e.g. https://dummyjson.com/users/1
method: # the HTTP method, such as GET, POST, PUT, DELETE, PATCH
parameters: # set the parameters to be passed to the API
headers: # set headers such as authorization tokens
body: # set body, in JSON or YAML, to pass data to the API
onSuccess: # fire an action when the API returns a 2**
onError: # fire an action when the API returns a 4**

# add more APIs as you need
mySecondApi:
```
## GET call without authentication
For public APIs that do not require authentication, you typically need only the URI and the method.
```yaml
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
```
## GET call with bearer token
APIs might be secured by requiring a token. This token is typically passed as a header parameter named `Authorization`.

```yaml
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
headers:
Authorization: "Bearer <<add token here>>"
```


## GET call with API key

Some API providers would issue keys to their customers. Typically, the API provider would require the key to be passed a parameter. Check with API provider documentation on what the name of this parameter is. Here, we use `apiKey` as an example.

```yaml
API:
getUser:
uri: https://dummyjson.com/users/1
method: GET
parameters:
apiKey: "<<add key here>>"
```


## POST call with data

Typically you use POST calls with a body to pass data from the frontend to the backend. You can specify the body of the API, and use inputs to pass them dynamically.

```yaml
API:
addProduct:
inputs:
- productTitle
uri: https://dummyjson.com/products/add
method: POST
body:
title: '${productTitle}' # example of a dynamic data that is set based on the inputs
source: MyApp # example of a static data that is always passed
```
47 changes: 47 additions & 0 deletions APIs/graphql.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# GraphQL

Use Case (Social Media): GraphQL is particularly beneficial in scenarios like social media, where large-scale data is involved. It allows clients to request only the specific data they need, leading to quicker response times (1-2 seconds).
Efficiency: GraphQL enables clients to specify the exact data they want in a single query, reducing over-fetching and under-fetching.

```yaml
inputs:
- GQLInput
uri: ${env['graphQL_URL_'ensemble.storage]}
method: POST
headers:
Authorization: Bearer ${ensemble.storage.token.exp_token}
ContentType: "application/json"
body:
"query": |-
mutation UpdatePost($input: CreateUpdatePostInput!) {}
"variables": ${GQLInput}
```
HTTP Method:
GraphQL APIs typically use the HTTP POST method. In your example, the method is specified as POST.
```yaml
method: POST
```
URI (Uniform Resource Identifier):
The URI is typically a single endpoint for GraphQL APIs. In your example, the URI is parameterized with an environment variable (assuming graphQL_URL_ensemble.storage is provided at runtime).
```yaml
uri: ${env['graphQL_URL_'ensemble.storage]}
```
Headers:
GraphQL API requests often include headers for authentication or specifying the content type. In your example, you have headers for Authorization (Bearer token) and ContentType (set to "application/json").
```yaml
headers:
Authorization: Bearer ${ensemble.storage.token.exp_token}
ContentType: "application/json"
```
Request Body:
GraphQL API requests use a structured query language in the request body. The key part here is the "query" field, where you define the GraphQL query or mutation. In your example, you are using a mutation called "UpdatePost," and the query is parameterized with ${GQLInput}.
```yaml
body:
"query": |-
mutation UpdatePost($input: CreateUpdatePostInput!) {}
"variables": ${GQLInput}
```
33 changes: 33 additions & 0 deletions APIs/headers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# How to set headers including authorization header

Setting headers, including the crucial "Authorization" header, is a key aspect of enhancing security and enabling proper authentication.

The headers section is used to specify additional information that should be included in the HTTP request headers when making the API call.

The value of the "Authorization" header is set to a bearer token, and the token value is dynamically inserted using ${token}.

The "Bearer" type in the "Authorization" header signifies that the presented token should be treated as a bearer token, providing access to the associated user or client without additional proof of possession.

````yaml
uploadProfilePicture:
method: POST
uri: https://api.ensemble.co/api/v2/profile-picture
headers:
Authorization: Bearer ${ensemble.storage.token.access_token}
onResponse:
executeCode:
body: |
//@code
console.log(response.body);
ensemble.storage.image = response.body;
````
````yaml
API:
getNames:
uri: https://myuri.com
method: 'POST'
headers:
"Authorization": "Bearer ${token}"
onResponse: |
// Code for handling the response goes here
````
Loading

0 comments on commit dabc947

Please sign in to comment.