Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More granular indirection needed in Discordia's REST/HTTP API #252

Open
SinisterRectus opened this issue Aug 4, 2020 · 3 comments
Open
Milestone

Comments

@SinisterRectus
Copy link
Owner

The Discord API is split into two major protocols: a REST API over HTTPS and a real-time gateway API over WSS.

Discordia has several layers of abstraction between the user and Discord's REST API.

At the lowest layer, Discordia depends on the coro-http library to make HTTPS requests, where raw strings and tables are submitted and returned by a single awaitable function call. This is simple and easy to use, but for a Discord API user, extra work must be done to prepare the requests. This work is handled by Discordia's API class.

In the API class, there is a unique method for each documented Discord API endpoint. These methods accept and normalize variable user input for endpoint parameters plus relevant payload and query information. The normalized data is then passed to a central request method that does the URL construction, JSON and multipart encoding, request header population, and pre-request ratelimiting. The data is then passed to a commit method that makes the request and does the JSON decoding, response header consumption, error handling, and post-request ratelimiting. The response is returned back the individual endpoint method as a JSON data table or an error string in case of failure.

These API methods are not exposed to the user. Instead, they are used throughout the various public classes. For example, users may call Guild:createRole, which calls API:createGuildRole internally and returns a Role object on success. In this case, there is no way to access the raw JSON input or output and there is no way to create a new role without first having access to the full guild object (the Discord API only requires the guild ID). Additionally, Discordia generally only supports editing one object property at a time while internal methods edit many at once. For example, Role:setName and Role:setColor must be called individually, yet both corresponding properties are edited by the same internal Role:_modify and API:modifyGuildRole methods. For some users, it may be beneficial to have access to raw JSON input/output, it may be beneficial to "hierarchy jump" (for example, to create or edit a role without having a guild object), and it may be beneficial to modify properties in bulk instead of with individually abstracted methods. For these reasons, it makes sense to consider more granular indirection in designing the REST part of Discordia 3.0.

@SinisterRectus SinisterRectus added this to the 3.0 milestone Aug 4, 2020
@SinisterRectus
Copy link
Owner Author

I'm thinking about this more and I'm realizing that it adds a lot of complexity that I don't want to add at the moment. I'll see if I can find some compromise. That may include just allowing access to the raw API class or at least exposing some bulk modify methods.

@SinisterRectus
Copy link
Owner Author

A draft of this has actually been implemented in 3.0. See commit 1ccbd03. I will leave this issue open for now.

@SinisterRectus SinisterRectus reopened this Sep 8, 2020
@SinisterRectus
Copy link
Owner Author

Almost a year after I dismissed this idea, I am finding that it now makes the library development a bit easier. It's extra work to maintain client methods plus individual container methods, but it is easier to keep track of everything that the library can do when the core functionality is located in one place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant