# REST API

{% hint style="info" %}
This guide assumes you have the Adminly API hosted using Adminly cloud service or are self-hosting on an existing web application. If you do not yet have Adminly installed, please follow our guides on installation.
{% endhint %}

## Schema

You can explore the schema of your connected database using the schema endpoint:

```
/adminly/schema
```

you can also explore the schema of any particular table using the endpoint:

```
/adminly/schema/<table_name>
```

## Collections

Fetch any table in your database using the table name as the end point.

## Fetch rows from table \<table\_name>.

<mark style="color:blue;">`GET`</mark> `https://api.myapp.com/adminly/<table_name>`

#### Query Parameters

| Name        | Type    | Description                                                   |
| ----------- | ------- | ------------------------------------------------------------- |
| filters     | String  | See **filter** documentation for more details.                |
| order       | String  | See **sorting** documentation for more details.               |
| select      | String  | See **select** documentation for more details.                |
| keywords    | String  | See **search** documentation below for more details.          |
| belongs\_to | String  | See **associations** documentation below for more details.    |
| has\_many   | String  | See **associations** documentation below for more details.    |
| habtm       | String  | See **associations** documentation below for more details.    |
| page        | Integer | The current page. Default  **1**.                             |
| per\_page   | Integer | The number of results to return per\_page. Default is **20**. |

{% tabs %}
{% tab title="200: OK Returns " %}

```javascript
{
    // Response
}
```

{% endtab %}
{% endtabs %}

## Filtering

The REST API uses a flexible and expressive query syntax for filtering table records. Filters can also combined with an `and` operation using a comma separated values.

| Operator | Value |
| -------- | ----- |
| eq       | =     |
| neq      | !=    |
| gt       | >     |
| get      | >=    |
| lt       | <     |
| lte      | <=    |
| in       | in    |

```
filters=<column1>:<operator>:<value>,<column2>:<operator>:<value>
```

Example query:

```
GET /adminly/api/movies?filters=ratings:gte:3.5,released:eq:true 
```

{% hint style="info" %}
The **in** operator accepts an array of values that is a comma separated list of values enclosed in brackets. For example user\_id`:in:[1,2,3]` finds all records where user\_id is 1,2 or 3.
{% endhint %}

## Sorting

You can sort fields using the `order` parameter. The `order` paremeter uses the following syntax:

```
order=<column>:<sort_direction>
```

| sort\_direction |                                         |
| --------------- | --------------------------------------- |
| asc             | Sort by ascending values (low to high)  |
| desc            | Sort by descending values (high to low) |

Example query:

```
GET /adminly/api/users?order=last_name:desc
```

## Select

Select fields allow you to return only specific fields from a table, similar to the SQL select statement. Select fields follows the query pattern:

```
<field>:<aggregation>
```

Aggregations are optional and will perform a group operation on the field. If the aggregation field is omitted, then select will only return the selected columns during serialization.&#x20;

| Aggregation |               |
| ----------- | ------------- |
| avg         | average value |
| sum         | sum of values |
| max         | maximum value |
| min         | minimum value |

Example query:

```
GET /adminly/movies?select=rating:avg&per_page=1000
```

## Pagination

You can paginate table records using the `page` and `per_page` params. By default `page` is set to **1** and `per_page` is set to **20.**&#x20;

```
page=<number>&per_page=<number>
```

| Parameter | Description                    |
| --------- | ------------------------------ |
| page      | The page of results            |
| per\_page | The number of results per page |

## Full-text Search

The REST API supports full-text search using the native search capabilities of PostgreSQL. For relational databases not running on PostgreSQL, you must specify the column to search since the operation will perform a `like` or `ilike` query.&#x20;

```
keywords=<search_term>
```

{% hint style="info" %}
Full-text search will query all fields in the table including `jsonb` field types.
{% endhint %}

For non-PostgreSQL databases:

```
keywords=<search_term>:<column>
```

Example query:

```
GET /adminly/movies?keywords=Star+Wars
```

{% hint style="info" %}
Full-text search is only available with PostgreSQL databases since it leverages the native search capabilities of PostgreSQL.&#x20;
{% endhint %}

## Associations

One of the most powerful features of Adminly is the ability to dynamically define relationships between collections (tables) and return nested results. Adminly currently supports `belongs_to`,`has_many`, and `habtm` (has and belongs to many) relationships.&#x20;

### Belongs to

You can define a `belongs_to` relationship using the syntax:

```
belongs_to=<table_name>:<foreign_key>:<association_name>
```

| Parameter          | Description                                            |
| ------------------ | ------------------------------------------------------ |
| `table_name`       | The name of the foreign table.                         |
| `foreign_key`      | The foreign key from the foreign table.                |
| `association_name` | The name that will be serialized in the JSON response. |

Example query:

```
GET /adminly/movies?belongs_to=producers:movie_id:producer
```

### Has many

You can find all relationships that are joined using a has\_many association.&#x20;

```
has_many=<table_name>:<foreign_key>:<association_name>
```

|                    |                                                        |
| ------------------ | ------------------------------------------------------ |
| `table_name`       | The name of the foreign table.                         |
| `foreign_key`      | The foreign key from the foreign table.                |
| `association_name` | The name that will be serialized in the JSON response. |

```
GET /adminly/movies?has_many=actors:movie_id:cast
```

### Has and belongs to many (HABTM)

Has and belongs to many associations relate tables in a database through a join table. Currently the join table is required to follow the Ruby on Rails naming conventions for the query to work. Namely, the join table should have column names that match the table names.&#x20;

{% hint style="info" %}
To learn more about the naming conventions required for a `habtm` query, please refer to the [Ruby on Rails ActiveRecord guide](https://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association) on associations.
{% endhint %}

You can define a habtm relationship with the syntax:

```
habtm=<foreign_table>:<join_table>:<association_name>
```

| Parameter          | Description                                                                   |
| ------------------ | ----------------------------------------------------------------------------- |
| `foreign_table`    | The name of the foreign table.                                                |
| `join_table`       | The name of the join table that joins the  active table to the foreign table. |
| `association_name` | The name that will be serialized in the JSON response.                        |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.adminly.com/reference/api-reference/rest-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
