-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
115-Device Capabilities Hierarchy has been added to the side navigati…
…on, also moved all files into the docs folder of docsify
- Loading branch information
Showing
271 changed files
with
13,468 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
```` |
Oops, something went wrong.