question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

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

See original GitHub issue

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.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:10 (10 by maintainers)

github_iconTop GitHub Comments

3reactions
monbreycommented, Jun 11, 2022

builders isn’t necessarily meant for do-it-once-and-never-touch-it-again payloads

As for setComponents or anything similar… Is there an actual use case for this method? When would you add components only to then set the entire action row again?

I feel like these points contradict each other and ignore a lot of what I said in the first comment. The attitude towards component builders continues to be focused on building them for the first time, with no consideration for editing.

ButtonComponent.from(theData).setDisabled() is not sufficient. How do you then replace that one button in what could be up to 5x5 rows?

It should not be necessary to clone 5 action rows / 25 buttons using Component.from just to edit one nested item.

Maybe you wouldn’t set all 5 - this is a better argument for spliceComponents, but still. Consider the editing usecase.

1reaction
monbreycommented, Jul 7, 2022

It shouldn’t be up to builders to aid in editing a components, that’s up to you when using them

If that’s a design decision to be made for component builders, then so be it, they can only build. However it should be acknowledged that this greatly undercuts their usefulness and ignores user stories that I personally would consider must-haves were this a product being designed based on the requirements of actual developers,

Read more comments on GitHub >

github_iconTop Results From Across the Web

RFC: New Validation Component - Laminas Project Community
This Request for Comments proposes a new component targeting validation that will eventually replace zend-validator, but initially ...
Read more >
RFC: Creating Dancer2 validation plugin. - PerlMonks
and so for each field received from the user, I want to use a construction like (age => 'integer'). And here you should...
Read more >
[RFC] Attributes v2 - externals.io
Hi all,. I want to resurrect Dmitrys Attributes RFC that was rejected for 7.1 in 2016 with a few changes, incorporating feedback from...
Read more >
Multicast in MPLS/BGP IP VPNs RFC 6513 - IETF Datatracker
The use of mLDP on the PE-CE interface is described in [MVPN-BGP]. ... We will refer to these multicast routing instances as "VPN-specific...
Read more >
RFC 5210: A Source Address Validation Architecture (SAVA ...
The SAVA Device uses the session key to authenticate the signature carried in the packet so that it can validate the source address....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found