solidusio / solidus

🛒 Solidus, the open-source eCommerce framework for industry trailblazers.
https://solidus.io
Other
4.96k stars 1.28k forks source link

Remove the solidus_backend dependency on solidus_api #4775

Open elia opened 1 year ago

elia commented 1 year ago

Allow solidus installation that are not using the API to skip installing solidus_api altogether. All of the current endpoints could be moved to backend controllers making use of the authenticated session instead of the api token, allowing an even simpler setup and further cleanup.

There are a few API endpoints that are currently being used by the backend:

$ grep -r "api/" backend ``` backend/app/assets/javascripts/spree/backend/shipments.js: url: Spree.pathFor('api/shipments/' + this.shipment_number + '/ship'), backend/app/assets/javascripts/spree/backend/shipments.js: var url = Spree.pathFor('api/shipments/' + shipment_number); backend/app/assets/javascripts/spree/backend/shipments.js: path = Spree.pathFor("api/shipments/transfer_to_location"); backend/app/assets/javascripts/spree/backend/shipments.js: path = Spree.pathFor('api/shipments/transfer_to_shipment'); backend/app/assets/javascripts/spree/backend/shipments.js: url: Spree.pathFor('api/variants/' + this.variant_id), backend/app/assets/javascripts/spree/backend/option_value_picker.js: $.get(Spree.pathFor('api/option_values'), { backend/app/assets/javascripts/spree/backend/option_value_picker.js: url: Spree.pathFor('api/option_values'), backend/app/assets/javascripts/spree/backend/variant_autocomplete.js: url: Spree.pathFor('api/variants/' + element.val()), backend/app/assets/javascripts/spree/backend/variant_autocomplete.js: url: Spree.pathFor('api/variants'), backend/app/assets/javascripts/spree/backend/adjustments.js: url: Spree.pathFor('api/orders/' + window.order_number + '/coupon_codes'), backend/app/assets/javascripts/spree/backend/option_type_autocomplete.js: url: Spree.pathFor('api/option_types'), backend/app/assets/javascripts/spree/backend/option_type_autocomplete.js: url: Spree.pathFor('api/option_types'), backend/app/assets/javascripts/spree/backend/models/order.js: urlRoot: Spree.pathFor('api/orders'), backend/app/assets/javascripts/spree/backend/models/order.js: url: Spree.pathFor('api/checkouts/' + this.id + '/advance'), backend/app/assets/javascripts/spree/backend/models/order.js: url: Spree.pathFor('api/orders/' + this.id + '/empty'), backend/app/assets/javascripts/spree/backend/models/stock_item.js: return Spree.pathFor('api/stock_locations/' + this.get('stock_location_id') + '/stock_items'); backend/app/assets/javascripts/spree/backend/models/shipment.js: urlRoot: Spree.pathFor('api/shipments'), backend/app/assets/javascripts/spree/backend/models/payment.js: return Spree.pathFor('api/orders/' + this.get('order_id') + '/payments') backend/app/assets/javascripts/spree/backend/models/taxonomy.js: urlRoot: Spree.pathFor('api/taxonomies') backend/app/assets/javascripts/spree/backend/taxons.js: url: Spree.pathFor('api/classifications'), backend/app/assets/javascripts/spree/backend/taxons.js: url: Spree.pathFor('api/taxons'), backend/app/assets/javascripts/spree/backend/taxons.js: url: Spree.pathFor('api/taxons/products'), backend/app/assets/javascripts/spree/backend/admin.js: url: Spree.pathFor('api/checkouts/' + window.order_number + '/advance') backend/app/assets/javascripts/spree/backend/collections/states.js: return Spree.pathFor('api/states?country_id=' + this.country_id) backend/app/assets/javascripts/spree/backend/views/order/customer_select.js: url: Spree.pathFor('api/users'), backend/app/assets/javascripts/spree/backend/taxon_autocomplete.js: url: Spree.pathFor('api/taxons'), backend/app/assets/javascripts/spree/backend/taxon_autocomplete.js: url: Spree.pathFor('api/taxons'), backend/app/assets/javascripts/spree/backend/user_picker.js: url: Spree.pathFor('api/users'), backend/app/assets/javascripts/spree/backend/user_picker.js: url: Spree.pathFor('api/users'), ```

That is:

PUT api/checkouts/`ORDER_NUMBER/advance
PUT api/classifications
GET api/option_types
GET api/option_values
GET api/orders
POST api/orders/ORDER_NUMBER/coupon_codes
PUT api/orders/ORDER_NUMBER/empty
GET api/orders/ORDER_NUMBER/payments
GET api/shipments
PUT api/shipments/SHIPMENT_NUMBER
PUT api/shipments/SHIPMENT_NUMBER/ship
POST api/shipments/transfer_to_location
POST api/shipments/transfer_to_shipment
GET api/states?country_id=COUNTRY_ID
GET api/stock_locations/STOCK_LOCATION_ID/stock_items
GET api/taxonomies
GET api/taxons
GET api/taxons/products
GET api/users
GET api/variants
GET api/variants/VARIANT_ID

A few things need to be taken into account:

tvdeyen commented 1 year ago

I like the general idea of cleaning things up, but have some questions:

waiting-for-dev commented 1 year ago

Until v4 we should have some sort of configuration for switching between using the API endpoints and the the local backend controllers (unless https://github.com/orgs/solidusio/teams/core-team thinks differently)

We can use versioned defaults for that.

elia commented 1 year ago

I like the general idea of cleaning things up, but have some questions:

@tvdeyen thanks for the question, happy to clarify the proposal 🙌

  • Are we using these endpoints solely in the admin?

Yes, the point being for the admin to be self-reliant, so it can be installed only requiring soliduscore (out of solidus* gems).

  • Would we remove endpoints from the API if they are solely used in the admin?

That's an option, but it should follow a full deprecation cycle. It's also true that the current endpoints are generally not justified by their usage as only a few of them are used by the classic frontend and none are used by the starter frontend.

  • Are you planning to duplicate endpoints if they are shared between Backend and API?

Yes, this should be perceived as good duplication as it would allow local endpoints to be more precise and possibly for service objects, supporting classes, or otherwise new model methods to be added in order to move behavior from api controllers toward solidus_core.

In some cases it might make much more sense not to return JSON anymore and instead render a page or partial or specialized JS.