avo icon indicating copy to clipboard operation
avo copied to clipboard

REST API

Open adrianthedev opened this issue 3 years ago • 7 comments

Refinement

  • [ ] should support read and write

Endpoints

POST   /resources/teams(.:format)
GET    /resources/teams/new(.:format)
GET    /resources/teams/:id/edit(.:format)
GET    /resources/teams/:id(.:format)
PATCH  /resources/teams/:id(.:format)
PUT    /resources/teams/:id(.:format)
DELETE /resources/teams/:id(.:format)

Get a record

{
  "record": {
    "id": 123,
    "name": "Adrian"
  }
}

Proposal

Create a JSON API endpoints using the resource configuration. Read-only in the initial iteration.

Example

A resource like the one below to expose a /resources/teams REST API endpoints for:

GET    /resources/teams(.:format)
POST   /resources/teams(.:format)
GET    /resources/teams/new(.:format)
GET    /resources/teams/:id/edit(.:format)
GET    /resources/teams/:id(.:format)
PATCH  /resources/teams/:id(.:format)
PUT    /resources/teams/:id(.:format)
DELETE /resources/teams/:id(.:format)
class TeamResource < Avo::BaseResource
  self.title = :name
  self.includes = [:admin, :team_members]

  field :id, as: :id
  field :name, as: :text, sortable: true
  field :url, as: :text
  field :logo, as: :external_image, as_avatar: :rounded do |model|
    if model.url
      "//logo.clearbit.com/#{URI.parse(model.url).host}?size=180"
    end
  end
end

Benefits

This could make scaffolding API endpoints very easy.

Actions

Actins could turn into their own paths, mapping parameters to fields and using their logic to execute that action

Filters

Filters could take in params and use their logic to filter the records in the response.

Views

Maybe add a new view with the visibility helpers hide_on: :json?

Approach (initial iteration)

Have a route and controller that automatically generates the endpoints. Each endpoint would expose the fields that have been configured in the resource.

We'll have a generator that the user runs to generate those controllers. Each controller will handle one resource.

Controller methods

Let's try to keep as much logic as we can in those controllers and allow the user to take control by overriding those methods similar to how we do it with destroy_success_action, and destroy_fail_action.

Property visibility

Each endpoint will take into account the visibility settings. Ex: on /api/resources/teams each object will have only the properties that are visible on the Index view. Same for other views.

We might want to add a few other helpful methods like process_record where the user can take more control over the data manipulation.

Rest structure

Let's take inspiration from the greats. We don't want to reinvent the wheel here.

  • https://shopify.dev/docs/api/admin-rest/2024-10/resources/product#get-products?ids=632910392,921728736
  • https://bullettrain.co/docs/api
  • https://github.com/PedroAugustoRamalhoDuarte/avo-api

Endpoint versioning

Each controller/controller set will land in a version directory. The user can generate new versions of the API in new directories.

app/controllers/api/v1/products.rb

Endpoint structure

{
  records: [ ... ], # array of records
  pagination: { # open to suggestions
    page: 3,
    total_pages: 12
    ...
  }
}

adrianthedev avatar Aug 17 '22 17:08 adrianthedev

I upvote for this

tracyloisel avatar Dec 09 '22 12:12 tracyloisel

Hi Adrian, any chance this is on the roadmap for v3?

iyerushalmi avatar Feb 14 '23 18:02 iyerushalmi

I'd like to start working on that after we launch V3. We don't yet have it on the roadmap.

adrianthedev avatar Feb 14 '23 19:02 adrianthedev

Hello @adrianthedev with the hype from Tropical.rb, i have made a small poc to this feature: https://github.com/PedroAugustoRamalhoDuarte/avo-api

It s a very minimal example for us to see the necessary work to make this feature. Only working for show endpoint right now

You rule @PedroAugustoRamalhoDuarte!

Let me give it a spin next week. Maybe we can release it as a separate gem.

adrianthedev avatar Apr 12 '24 19:04 adrianthedev