Closed Dhghomon closed 1 year ago
I think the general flow should be:
- Basic queries
- derive Queryable
- Arguments
- Query methods explained (where to use single, required single, why json are special methods)
- Transactions
- Configuring pool (different methods of with_* pattern, although, not sure what are good examples of that, maybe query/transaction timeout)
- How to organize things? Do we have to pass the pool everywhere? What's the downsides of putting it into a static var (that is the configuration)?
Other things can be moved around to a different documentation pages.
On general flow there's a bit of a dilemma here because Queryable is the slickest way to use the client but new users are probably more likely to flock to
Maybe this could work:
Start with derive Queryable, followed by edgedb(json), then add the same example if it were to be done with
That dips into the 4. you mentioned here a bit earlier on but could be worth it since it avoids giving the impression that there's only one way to unpack into a Rust struct.
slickest way to use the client but new users are probably more likely to flock to because doing a .to_string() and then serde_json::from_str() is the most comfortable pattern. (My own experience was the same here, started out with json-ing everything before moving on to Queryable). That means we're doing something wrong. Either APIs are wrong or documentation is missing.
The edgedb(json)
attribute was made just to support migrations, which is an internal EdgeDB thing.
The attribute should be documented, but I don't see good use cases for that. Returning partially JSON values and partially not JSON makes little sense. Especially in our rich data model, where we discourage JSON columns.
On the othe hand, JSON output of EdgeDB is thing that should be used to directly send result to the client. So it's also not a use case for the attribute.
slickest way to use the client but new users are probably more likely to flock to because doing a .to_string() and then serde_json::from_str() is the most comfortable pattern. (My own experience was the same here, started out with json-ing everything before moving on to Queryable). That means we're doing something wrong. Either APIs are wrong or documentation is missing.
Okay, let me think...personally, I think what might have gotten me to use it before serde_json would have been a simplified (i.e. easily readable) example of the generated code. Usually when I see a macro in a crate I haven't used before I avoid it until I have an idea of exactly what it does, and to get an idea of what it does means checking out cargo expand and wading through a bit of that code, and in the meantime I tend to come across other ways of getting things done and forget to use the crate's macros. But if that were front and centre then I probably would have given it a try earlier. So maybe that's an option? ("The Queryable macro generates code that looks roughly like this: (insert example with lots of macro bits removed)")
The
edgedb(json)
attribute was made just to support migrations, which is an internal EdgeDB thing.The attribute should be documented, but I don't see good use cases for that. Returning partially JSON values and partially not JSON makes little sense. Especially in our rich data model, where we discourage JSON columns.
On the othe hand, JSON output of EdgeDB is thing that should be used to directly send result to the client. So it's also not a use case for the attribute.
That's good to know as I haven't been able to find a use case for the partial JSON attribute. Can strip it down to more minimal documentation then.
"The Queryable macro generates code that looks roughly like this: (insert example with lots of macro bits removed)"
The actual code is quite weird :( Although, you may come to a rough estimation that looks sensible to users. Generally you can compare it to serde::Serialize
.
"The Queryable macro generates code that looks roughly like this: (insert example with lots of macro bits removed)"
The actual code is quite weird :( Although, you may come to a rough estimation that looks sensible to users. Generally you can compare it to
serde::Serialize
.
I think I've come up with a nice way to demonstrate this to my past self that I want to convince to use the macro earlier rather than later without cluttering up the tutorial. First a quick struct and cargo expand
to grab the output, cleaned up the macro-y bits and stuck it in here:
https://github.com/Dhghomon/edgedb_rust_client_examples/blob/master/src/lib.rs#L12
Only 70 lines and looks close to human written. Then the tutorial will have a link to that for anyone who is curious (like my past self) and anyone who clones it will be able to quickly click around the methods to satisfy their curiosity.
Currently working on a lot of your other suggestions like changing order and tidying up by removing a lot of implementation details. (Also changing the order in the minimal example repo to emphasize using Queryable before showing other ways to unpack into a struct)
Okay @tailhook and @raddevon, once more from the top! The tutorial is now a lot shorter and mostly in the order tailhook suggested so maybe just read the whole tutorial.md afresh and see what you think.
Lacks tailhook's suggested part 7 though:
How to organize things? Do we have to pass the pool everywhere? What's the downsides of putting it into a static var (that is the configuration)?
It keeps feeling like getting into other people's implementation details and preferences whenever I try to put this one together - do you think we need it?
Getting back to this now that the 3.0 rush is over: @tailhook any thoughts on the changes made after your last feedback? Feels like it's getting closer to mergeable by now.
@tailhook is on extended leave now. @fantix can you take a look at this PR?
Yeah sure, will do!
The largest part of this PR is the tutorial.md file containing a tutorial for the Rust client. Also includes:
@raddevon I'll ping you too in case you want to give the tutorial.md a look.