API Design #1

Open
opened 2021-12-11 16:42:32 +00:00 by glyph · 7 comments
Owner

@notplants

Considering that golgi may come to be used by many diverse developers, I think it's a good idea to design the API before writing any more code. Instead of trying to sketch out the entire surface up-front, we can focus on the features we will need for PeachPub v1. That should be enough functionality to define a clear pattern which future features can adhere to.

I believe we had previously discussed offering lower-level calls and also exposing higher-level calls for convenience. As I recall, oasis was used as an example of what these calls could look like (see src/models.js).

So this low-level : high-level distinction might look something like this:

// low-level calls
sbot_client.follow(id);
sbot_client.block(id);
sbot_client.unfollow(id);

// high-level call
sbot_client.set_relationship(id, relationship);

// low-level calls
sbot_client.follows(id_a, id_b);
sbot_client.blocks(id_a, id_b);

// high-level call
match sbot_client.get_relationship(id_a, id_b) {
    Relationship::Following => ...,
    Relationship::NotFollowing => ...,
    Relationship::Blocking => ...,
}

We will also need to consider what types we'd like to define for the API. Existing types in kuska can be found in src/api/dto/content.rs.

@notplants Considering that golgi may come to be used by many diverse developers, I think it's a good idea to design the API before writing any more code. Instead of trying to sketch out the entire surface up-front, we can focus on the features we will need for PeachPub v1. That should be enough functionality to define a clear pattern which future features can adhere to. I believe we had previously discussed offering lower-level calls and also exposing higher-level calls for convenience. As I recall, oasis was used as an example of what these calls could look like (see [src/models.js](https://github.com/fraction/oasis/blob/e42af4884ed443802355354fce185e3b2b56cff7/src/models.js)). So this low-level : high-level distinction might look something like this: ```rust // low-level calls sbot_client.follow(id); sbot_client.block(id); sbot_client.unfollow(id); // high-level call sbot_client.set_relationship(id, relationship); // low-level calls sbot_client.follows(id_a, id_b); sbot_client.blocks(id_a, id_b); // high-level call match sbot_client.get_relationship(id_a, id_b) { Relationship::Following => ..., Relationship::NotFollowing => ..., Relationship::Blocking => ..., } ``` We will also need to consider what types we'd like to define for the API. Existing types in kuska can be found in [src/api/dto/content.rs](https://github.com/Kuska-ssb/ssb/blob/master/src/api/dto/content.rs).
Owner

@glyph this looks good to me. Also think it still sounds good to have the high and low-level calls here, like we planned with go-sbotcli-rs.

From the current implementation of golgi, serde is already included, so this relieves the question of whether we need to hide high-level calls behind a feature flag (to allow for a low-level call version with no serde). Or did you intend to remove the dependency on serde?

To make a rough pass at an API,
I could go through this page https://server.commoninternet.net/pad/p/peachcloud-milestones,
and then for each thing we need, write a stub of what golgi function it would use.

I imagine the API still might change some as we actually build it out and see what we're missing or what could be streamlined, but that could be a start.

@glyph this looks good to me. Also think it still sounds good to have the high and low-level calls here, like we planned with go-sbotcli-rs. From the current implementation of golgi, serde is already included, so this relieves the question of whether we need to hide high-level calls behind a feature flag (to allow for a low-level call version with no serde). Or did you intend to remove the dependency on serde? To make a rough pass at an API, I could go through this page https://server.commoninternet.net/pad/p/peachcloud-milestones, and then for each thing we need, write a stub of what golgi function it would use. I imagine the API still might change some as we actually build it out and see what we're missing or what could be streamlined, but that could be a start.
Owner

Here is a pad where I started to do this: https://server.commoninternet.net/pad/p/golgi-api

Did it in a separate pad, so that we can discuss there etc., without overly polluting all the info in the original pad.

Here is a pad where I started to do this: https://server.commoninternet.net/pad/p/golgi-api Did it in a separate pad, so that we can discuss there etc., without overly polluting all the info in the original pad.
Owner

perhaps discussing this together on a call would be easiest?

perhaps discussing this together on a call would be easiest?
Author
Owner

@notplants

Thanks for sketching out the API; the doc looks great!

From the current implementation of golgi, serde is already included, so this relieves the question of whether we need to hide high-level calls behind a feature flag (to allow for a low-level call version with no serde). Or did you intend to remove the dependency on serde?

Serde is already included as a dependency in kuska_ssb so we do not gain anything by avoiding it in golgi.

perhaps discussing this together on a call would be easiest?

Sounds great.

@notplants Thanks for sketching out the API; the doc looks great! > From the current implementation of golgi, serde is already included, so this relieves the question of whether we need to hide high-level calls behind a feature flag (to allow for a low-level call version with no serde). Or did you intend to remove the dependency on serde? Serde is already included as a dependency in `kuska_ssb` so we do not gain anything by avoiding it in golgi. > perhaps discussing this together on a call would be easiest? Sounds great.
Author
Owner

Linking to the discussion in PR #18 about API design.

The question is essentially: to what degree should the golgi API match the JS MUX-RPC API?

A useful follow-up question: what are the trade-offs of trying to emulate the JS API?

My brief thoughts: the JS API (which is spread across many, many modules) was authored by loads of different devs, each of whom undoubtedly had different ideas about API design, over the course of many years. The API reflects that context.

With golgi being developed by two of us at one time, we have an opportunity to create a clear and consistent API.

The main benefit I see to emulating the JS API is that JS SSB devs who are already familiar with their API will find it easier to pick up golgi.

The main downside I see is that we end up with a hodge-podge API that is confusing and frustrating, especially to developers who have no experience with the JS SSB stack.

My assumption at this point is that most golgi users will not have a background with the JS API.

@notplants

I'd be interested to hear what your motivation is for wanting to emulate the JS API.

Linking to the discussion in [PR #18](https://git.coopcloud.tech/golgi-ssb/golgi/pulls/18#issuecomment-11641) about API design. The question is essentially: to what degree should the golgi API match the JS MUX-RPC API? A useful follow-up question: what are the trade-offs of trying to emulate the JS API? My brief thoughts: the JS API (which is spread across many, many modules) was authored by loads of different devs, each of whom undoubtedly had different ideas about API design, over the course of many years. The API reflects that context. With golgi being developed by two of us at one time, we have an opportunity to create a clear and consistent API. The main benefit I see to emulating the JS API is that JS SSB devs who are already familiar with their API will find it easier to pick up golgi. The main downside I see is that we end up with a hodge-podge API that is confusing and frustrating, especially to developers who have no experience with the JS SSB stack. My assumption at this point is that most golgi users will not have a background with the JS API. @notplants I'd be interested to hear what your motivation is for wanting to emulate the JS API.
Owner

@glyph that seems like a good breakdown to me.

my only argument towards including the muxrpc functions would be more along the lines of providing the low-level calls that are implemented. sort of like when we were making go-sbotcli-rs... to say, here are all the muxrpc calls that are available, and you can call them if you would like to.

but agreed that could complicate documentation and explaining things, to say here is the API that we actually use and think is good,
and here are the legacy muxrpc calls that we dont really use (e.g. friends.follow) but you could use if you really want to

@glyph that seems like a good breakdown to me. my only argument towards including the muxrpc functions would be more along the lines of providing the low-level calls that are implemented. sort of like when we were making go-sbotcli-rs... to say, here are all the muxrpc calls that are available, and you can call them if you would like to. but agreed that could complicate documentation and explaining things, to say here is the API that we actually use and think is good, and here are the legacy muxrpc calls that we dont really use (e.g. friends.follow) but you could use if you really want to
Owner

I guess on the plus side for muxrpc,
when I learned there was a muxrpc API, while learning scuttlebutt, was the first time I started to feel like there was anything consistent.

go-sbot implements most of the muxrpc calls,
js implements them,
kuska was aware of them

now that I'm thinking about,
muxrpc are also the API that sbots expose to each other,

so, even if imperfect, there is some reason, to create consistency with the pack, to try to also provide these methods,
the one inkling of a common API that ssb seems to have...

this might be a bad idea, but I just imagined prefacing our muxrcp methods with mux...

e.g.
mux_friends_follow
mux_friends_is_following
etc.

and then our golgi library calls these functions, while also defining its own API that is not directly tied to the muxrpc function names and interfaces

but idk just thinking out loud

I guess on the plus side for muxrpc, when I learned there was a muxrpc API, while learning scuttlebutt, was the first time I started to feel like there was anything consistent. go-sbot implements most of the muxrpc calls, js implements them, kuska was aware of them now that I'm thinking about, muxrpc are also the API that sbots expose to each other, so, even if imperfect, there is some reason, to create consistency with the pack, to try to also provide these methods, the one inkling of a common API that ssb seems to have... this might be a bad idea, but I just imagined prefacing our muxrcp methods with mux... e.g. mux_friends_follow mux_friends_is_following etc. and then our golgi library calls these functions, while also defining its own API that is not directly tied to the muxrpc function names and interfaces but idk just thinking out loud
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: golgi-ssb/golgi#1
No description provided.