Skip to content

RFC(builders): The interface, the validation, and the pains you have had with them so far #8015

@vladfrangu

Description

@vladfrangu

Preface: this RFC (Request For Comments) is meant to gather feedback and opinions for the 3 issues that will be mentioned down below. I understand builders tend to be quite a sensitive topic with everyone disagreeing on how it should be done, so please keep the feedback useful. Thanks!

This RFC aims to solve (hopefully once and for all) the three pain points of builders as they currently are done. The end goal is to decide what the interface should look like for all current and possibly future builders! It is split into 3 separate parts, denoted by the headings.

Before you answer, please read through the entire RFC, and don’t jump to answering just one question only. You don’t have to answer question 3 if you have nothing to add to it, but the other two would be super appreciated to receive answers to. Thanks for reading this, and now let’s get started~!


1. The interface

One of the key issue with the current builders is the lack of a consistent interface between the Application Command builders, the Message Component builders and the Embed builder.

As it stands at the time of writing this RFC:

  • Application command builders follow a nested approach, with .add* methods for each option type. The class’s fields represent the structure similar to how the api payload will look like.
  • Message component builders follow part of the same structure as application command builders, with some caveats (addComponents takes in any component, whereas add* in application command builders add just that one kind of options), some options that take in arrays allow rest parameters too (something that in my opinion is fine except for set* methods that should take in an array only). The class stores all data in a data property, and accesses it for setting/reading the properties in it
  • Embed builder also stores the actual api embed data in the data field. They also allow input in camelCase format, where no other builder allows (or should allow) that.

Several things need to be decided:

  1. How should the classes store the data that will be returned from toJSON() calls? In a data field or as the class fields themselves?
  2. Should addComponents be removed in favor of addButton, addSelectMenu and so on? Or should application command builders use addOption instead?
  3. Should nested objects in any builder be a raw object or should they be miniature builders? Consider EmbedBuilder#author. Currently it’s a raw object. Should it be brought in line with the other two builders and nest it as a builder?

My opinion on those 3 questions are:

  1. The class fields should represent as closely what the toJSON will return. Calling { ...builder } should return the same valid data as calling builder.toJSON() Well I changed my mind, we should instead use the data field, however no getters should be added pointing to said field
  2. ActionRowComponent should use the same interface as application command builders (one add* per component type)
  3. EmbedBuilder should get nested builders for such fields (with fallbacks allowed for objects for users if it’s gonna be such an issue).

2. The validation

Outside of application command builders, every other builder has 2 classes inside. An “Unsafe” class (which has 0 input validation) and a “Safe” class (which has validation for inputs (and quite fast validation at that)).

From my perspective, this split needs to be removed. The point of builders is to provide a consistent interface for creating api data. Creating two classes that achieve the same thing, even if one of them just extends the other, feels wrong and redundant. All builders should use validation by default¹. This would clean up a lot of the classes, and also remove the issue that other modules using builders need to export both safe and unsafe versions (the latter of which might scare users away).

¹: Validation should instead be able to be turned off at the validation library level (something that we have planned in shapeshift actually (work feedback that we agree would be a good addition)). That way, you can decide in your code if the validation should be turned on or off (for instance turn off validation automatically if in a production environment)


3. The pain points

This point is more less an open page for you to air out what frustrations you’ve encountered with the interface. For this, I’d prefer if you sticked to issues related more to consistency or type issues or performance worries (etc), and not the fact the interface has/will change again. The builders package is still not on version 1, meaning we’re still more-less in development to a degree.

Feel free to add anything that you think would improve the overall experience for everyone.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions