-
Notifications
You must be signed in to change notification settings - Fork 5
feat(Coder plugin): expose Coder SDK to Backstage end-users #132
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! One thing I wonder about, from a user's perspective, is that the connection between the sdk and auth is not immediately obvious. Like, coming from other rest sdks, I think I would expect something like this: scratch that, see below
const sdk = makeCoderSdk(url, "token")
sdk.getWorkspaces()
Or to use Coder's auth provider:
const { token } = useCoderAuth() // Triggers the auth popup if no token yet
const sdk = makeCoderSdk(url, token)
sdk.getWorkspaces()
BackstageHttpError.isInstance(queryError) && | ||
queryError.status === 401; | ||
|
||
if (!shouldRevalidate) { | ||
return; | ||
} | ||
|
||
isRevalidatingToken = true; | ||
isRevalidating = true; | ||
await queryClient.refetchQueries({ queryKey: sharedAuthQueryKey }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not related to this PR, just a question because I think I might have skipped over this before or I just forgot.
This is not making the fetches again on a 401, right? That would just result in another 401. Is it to clear out the data or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's sort of both? The logic spies on any 401s made for the currently-loaded query client, regardless of whether the 401 was for a Coder query or not.
Since we let the user supply their own Query client, the thinking was that even if a 401 triggers on a non-Coder query, it might help to revalidate the token, to handle cases like bad internet connections
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the limitations of storing the auth validity state with React Query is that normally, the current state is tied to one specific API function, with one specific query key
So React Query doesn't automatically know that when a non-auth query function errors out, that the underlying auth is probably invalid, too.
Though now that I think about it, I should be able to update the auth state directly when a Coder query fails. Let me see if I can't get that fixed really quick
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Think I have this improved now!
Revisiting the logic also made me realize that we don't really need the custom BackstageHttpError
type anymore, now that we have Axios (it exposes a lot of the same properties)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, never mind. Some of the changes are causing the existing tests to fail.
I'll open a new issue about this, but just to keep the scope of this PR small, I went ahead and reverted the changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle cases like bad internet connections
I think they would get some network error rather than a 401. Getting a 401 should mean the server responded and the token is well and truly invalid, and will never be valid again (at least if the token generating system is done correctly hahaha).
Although, it is interesting to consider the case where maybe they have a proxy in front of Coder, and it is the proxy that returned a 401 and not Coder, and the token is actually still valid. Buuuuut I guess even in that case the second query will still always fail with a 401, since a 401 is not automatically recoverable.
regardless of whether the 401 was for a Coder query or not
Ohhhhhhh I see, they could use it to make a request to some other service, and that service might give a 401? That does sound tricky! I see the use of the revalidate for this case but I agree it would be cool if it could be scoped to Coder queries.
plugins/backstage-plugin-coder/src/components/CoderProvider/CoderAuthProvider.tsx
Outdated
Show resolved
Hide resolved
* @file Defines a couple of wrappers over React Query/Tanstack Query that make | ||
* it easier to use the Coder SDK within UI logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do most Backstage users use React Query? I worry we are abstracting too early.
If we just expose the base useCoderSdk
and let users hook it up however they need, that seems most ideal to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sure some of them do, but Backstage's default recommendations don't include it
I cover this in the README PR, but there are a lot of limitations around useEffect
/useAsync
, so I figured it would help to provide an easier way to bring RQ into the app. The plugin is still going to expose the SDK directly for people who want to wire things up in a more custom way
Oh yeah wait the whole reason is to make it Backstage-y with the |
@code-asher Yeah, I tried to improve the co-location for the auth/SDK stuff to make their relationship a little more obvious, but when I tried it, I think the changes made things more confusing. I tried adding some auth-based helpers to I agree that the SDK setup flow you posted would be nice, but I don't know how to make that play nicely with React and Backstage. We don't have to do things the Backstage way – we could make it so that the user has to initialize the Coder Client themselves (making sure it's initialized outside a render function), and then feed that to the rest of the app via React Context. That's not the Backstage way, but it is the React way, which is good enough for me The main thing I'm not 100% sure on is that, with the client being dependent on other Backstage APIs, you might have to jump through a ton of hoops to get feed those into the Coder Client since you lose access to API factories. It should be doable, but I'm not 100% sure if that might add more confusion, or might make the code even more complex |
eabccd5
to
a67fbcf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think useApi
like you have it now is the right abstraction to use for this.
Thinking out loud, maybe the relationship would be clearer if we had something like:
return new CoderClient({
apis: { urlSync, identityApi, coderAuthApi },
});
And then CoderClient
calls coderAuthApi.token()
or something.
It feels a bit more Backstage-y to me over the React-ish way we have it now with the auth provider context. But idk if it is worth thinking about right now. Maybe when we revisit with oauth, since that will be a Backstage API as well. Could be cool if you could decide whether to slot that in or the current version with the pasting.
I do still wonder about the additional React Query abstraction, but going to defer to you since you know first-hand the pain users will experience doing it themselves. 😱
@code-asher Yeah, this is definitely one area where I wish we had more active users to get feedback from. I definitely don't expect this to be the final design, but it feels like exposing the Coder API at all is going to a good way to entice people to try out the plugin, and get the feedback on how to make this better I just wish that, for a platform built with React, Backstage were integrated with it a little bit better. The fact that we have to weigh the tradeoffs between React-isms and Backstage-isms doesn't feel super great |
This 100%, could not agree more!! |
Part of #112
Changes made
useCoderQuery
hook that simplifies wiring up all the Coder plugin logic touseQuery
Example usage
This is from the end-user's perspective (
useEndUserCoderAuth
will already have been renamed to justuseCoderAuth
)Notes
useCoderMutation
hook, too, but decided to put it on the back-burner for now because: