elements icon indicating copy to clipboard operation
elements copied to clipboard

Allow sorting operations programmatically

Open romalytvynenko opened this issue 5 months ago • 2 comments

This PR adds ability to order operations programmatically.

The problem

Currently, Stoplight Elements renders operations in order they are defined in the OpenAPI document.

However, you may want to order endpoints in the way, the OpenAPI document structure won't allow it. Imagine you want to order operations like so:

GET /companies/{company}
POST /companies
DELETE /companies/{company}
GET /companies

The OpenAPI document cannot represent operations in the way you want them to get ordered simply due to the structure of OpenAPI document itself (operations are grouped within paths). So here is the specification you have for such operations:

{
    "/companies/{company}": {
        "get": {},
        "delete": {}
    },
    "/companies": {
        "post": {},
        "get": {}
    }
}

This results in operations rendered in the following order:

GET /companies/{company}
DELETE /companies/{company}
POST /companies
GET /companies

The solution

I propose to add the operationsSorter option to the API component which will allow to pass the sort function OperationSorter:

export type OperationsSorter = (a: IHttpOperation, b: IHttpOperation) => number;

Here is how it can be used – in this case I've added x-weight extension to an operation and sort operations by this extension's value.

This is the code of the story I've created:

export const WithOperationsSorter = Template.bind({});
const isNumber = (a: any): a is number => !isNaN(Number(a));
WithOperationsSorter.args = {
  operationsSorter: function (a, b) {
    if (!isNumber(a.extensions?.['x-weight']) || !isNumber(b.extensions?.['x-weight'])) {
      return 0;
    }
    return a.extensions!['x-weight'] - b.extensions!['x-weight'];
  },
  apiDescriptionDocument: operationsSorter,
};
WithOperationsSorter.storyName = 'With Operations Sorter';

Implementation considerations

I considered 2 possible points where the sorting can happen.

The first option is to sort it early, right after ServiceNode is created, but before operations are grouped.

The second option is to sort operations after they are grouped within each group and right before rendering the operations in layout components.

I tried both approaches and decided to go with the first approach – as a developer, I'd expect ServiceNode object to have operations sorted according to the provided operations sorter (in case a sorter has been provided via the options).

Thoughts?

Let me know what you think and if this is a good addition!

Elements Default PR Template

  • [x] Read CONTRIBUTING.md

Other Available PR Templates:

  • Release: https://github.com/stoplightio/elements/compare?template=release.md
    • [x] Read the release section of CONTRIBUTING.md

romalytvynenko avatar Jun 19 '25 11:06 romalytvynenko

Deploy Preview for stoplight-elements ready!

Name Link
Latest commit 7128a0de99e4fd138a7304f74a77d3c3e36bbe7f
Latest deploy log https://app.netlify.com/projects/stoplight-elements/deploys/68550f049fcd06000847e953
Deploy Preview https://deploy-preview-2802--stoplight-elements.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Jun 19 '25 11:06 netlify[bot]

Deploy Preview for stoplight-elements-demo ready!

Name Link
Latest commit 7128a0de99e4fd138a7304f74a77d3c3e36bbe7f
Latest deploy log https://app.netlify.com/projects/stoplight-elements-demo/deploys/68550f047ad5a30008ea01e7
Deploy Preview https://deploy-preview-2802--stoplight-elements-demo.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

netlify[bot] avatar Jun 19 '25 11:06 netlify[bot]

@romalytvynenko I tried out your PR. It works like a charm. Thanks for your effort!

Maybe you could add the operationsSorter option to docs/getting-started/elements/elements-options.md.

@Asmodeios: It would really be nice to see this PR accepted.

alfa-alex avatar Aug 27 '25 10:08 alfa-alex

@alfa-alex

I paused working on it as the CI was failing (I believe this is just flaky behavior, but I'm not sure) and I couldn't fix that. Also I'm not sure anymore if community PRs get merged/get feedback (that is fine, np).

I would be happy as well if this gets merged. I will definitely document if I understand whether it is going to accepter or not.

romalytvynenko avatar Aug 27 '25 10:08 romalytvynenko