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

Resolving User fields within the GQL schema #202

Closed
Tracked by #273
CocoisBuggy opened this issue Dec 6, 2022 · 4 comments
Closed
Tracked by #273

Resolving User fields within the GQL schema #202

CocoisBuggy opened this issue Dec 6, 2022 · 4 comments
Labels
dev dev task
Milestone

Comments

@CocoisBuggy
Copy link
Contributor

CocoisBuggy commented Dec 6, 2022

Why 🤔

The ability to have a comprehensive entity schema is the main upside of GraphQL. Being able to compose queries of all kinds is a massive bonus, and will encourage developers to implement more features on OpenTacos with a vastly softer learning curve - and a much easier local development setup.

leaving these resolves to Next /api calls is an under-utilization of GraphQL's core offering that may result in over lock-in to the NextJS framework if not addressed now.

Problem Spec

As the offering for Posts and Contributions evolve, having a more comprehensive GQL schema definition will improve developer ergonomics and could potentially reduce developer on-boarding friction in the future.

type History {
    id: ID!
    editedBy: String!
    operation: String!
    createdAt: Date!
    changes: [Change]
 }

Gives sufficiently authorized developers a road to resolving users themselves, but adds an unreachable or frustrating step for new devs who are unfamiliar with the service structure.

editedBy: String also does not communicate anything about the schema data relationship - another benefit of GQL schemas

Current model

I believe the current model would have NextJS do an additional fetch/join to get this data from Auth0. The proposal made here is to move that logic into the resolver to improve API ergonomics for current and incoming API functionality. The upcoming post mechanics being an example.

Resolving within a single GQL endpoint is going to become increasingly desirable as contributions become more fleshed out, and we will inevitably end up with masses of relational data in the mongo data-store (Ticks, Posts, media, change-history, comments).

Additionally, if we were ever to experiment with alternate U.I frameworks we would need to commit to much more work and technical risk, than if principal data were all available through a single GQL endpoint.

Proposed Solution

Add an additional type to the schema, making a more holistic experience for API consumers.

The type would naturally not expose any private user data, and would return the same data available within the various api handlers already extant within OpenTacos.

type User {
  "Globally unique static ID for this user"
  id: ID!
  "Globally unique, but mutable"
  userName: String!
  "If an Avatar exists for this user, it is available here"
  avatarUrl: String
}

which could allow resolution for current and future types in the schema:

type History {
    id: ID!
    editedBy: User!
    operation: String!
    createdAt: Date!
    changes: [Change]
 }

# example of another type that could use user, but does not exist
type Media {
   id: ID!
   author: User!
   tags: [MediaTagType!]
}

The above proposed User type is far from comprehensive, and I would suggest that a number of other relational resolvers would be sensible, something like:

type User {
  "Globally unique static ID for this user"
  id: ID!
  "Globally unique, but mutable"
  userName: String!
  "If an Avatar exists for this user, it is available here"
  avatarUrl: String
  joined: Date
  country: CountryCode
  bio: String

  recentContributions: [History!]
  lastContribution: History

  recentTags: [MediaTagType!]
  lastTag: MediaTagType

  recentTicks: [Tick!]
  lastTick: Tick

  recentPosts: [Post!]
  lastPost: Post
}

I don't intend to make the above type a part of this proposal; discussion will need to take place about what is appropriate to expose in the schema, and it can be added progressively after an initial implementation for simple field revolvers.

@vnugent vnugent added the dev dev task label Dec 7, 2022
@vnugent vnugent modified the milestones: v0.7, v0.6 Dec 7, 2022
@vnugent vnugent self-assigned this Dec 19, 2022
@vnugent
Copy link
Contributor

vnugent commented Dec 19, 2022

I'm going to have a stab at this. As of now Auth0 is our source of truth for user data. I'm hesitant to duplicate that information here.

For the time being, as you pointed out, we only store user UUIDs in the database, without the human-friendly nicknames which are needed on openbeta.io. It'd be great to resolve user name in the backend.

I think we can add a simple association collection to help us resolve user

type User {
  "Globally unique static ID for this user"
  id: ID!
  "Globally unique, but mutable"
  userName: String!
  createdDate: Timestamp
  modifiedDate: Timestamp
}

@vnugent vnugent added this to the v0.6 milestone Dec 19, 2022
@CocoisBuggy
Copy link
Contributor Author

I wasn't actually thinking of putting user data inside the mongo schema - rather allowing resolution of public user fields in the schema.

So the resolver layer would make the requests that NextJS is currently making. In the mongo database we really only NEED uuids for the time being 🤔

My thinking is the API is maximally useful to developers when the schema is complete, and doesn't resolve IDs divorced from nodes.

I do think it's a good idea to keep uuid + userName in mongo though, as they are the core identifiers and we'll be working with

@vnugent vnugent modified the milestones: v0.6, v0.7 Jan 28, 2023
@vnugent
Copy link
Contributor

vnugent commented Jan 28, 2023

Let's put this one our next milestone, v0.7

@vnugent vnugent removed their assignment Jan 28, 2023
@vnugent
Copy link
Contributor

vnugent commented May 3, 2023

I'm addressing this at the GQL layer in PR #273. All queries that return user uuid now return a user name.

https://github.com/OpenBeta/openbeta-graphql/pull/273/files#diff-d9b0865f2e8f841410cd4faf3e1e4a1fb7cb0b545f583f6adaad5841d7eaa58dR59

For the time being we still rely on resolving username by fetching uid.json. We will need to have a follow up task to store user name in the DB and support CRUD.

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

No branches or pull requests

2 participants