Hello!,
I want to ask the Apollo community’s opinion about handling public & private fields/queries/mutations in a One Graph implementation.
Context
We currently have two separate Apollo servers under a different endpoint.
/public
and /private
and each one returns a different schema.
-
/public
: used by our website/apps -
/private
: used by our admin panel
Requirements
- I want to prevent selecting private fields by mistake in our clients (web, apps)
- (optional) private fields shouldn’t be included in the schema
Possible Solutions
- separate private fields inside one field
type Query {
userById(id: Int!): User
}
type User {
# common fields, used by public (app, web) & private (admin)
id: ID!
firstName: String!
lastName: String!
# fields used only by private (admin)
private: UserPrivate # add authorization only to this field
}
type UserPrivate {
email: String!
phone: String!
bookings: [Booking!]
}
- separate Query & Types
type Query {
userById(id: Int!): User
userByIdPrivate(id: Int!): UserPrivate
}
type User {
id: ID!
firstName: String!
lastName: String!
}
type UserPrivate {
id: ID!
firstName: String!
lastName: String!
email: String!
phone: String!
bookings: [Booking!]
}
- Unions
type Query {
userById(id: Int!): User
}
union User = UserPublic | UserPrivate
type UserPublic {
id: ID!
firstName: String!
lastName: String!
}
type UserPrivate {
id: ID!
firstName: String!
lastName: String!
email: String!
phone: String!
bookings: [Booking!]
}
- Interfaces
type Query {
userById(id: Int!): User
}
# common fields
interface User {
id: ID!
firstName: String!
lastName: String!
}
type UserPublic implements User {
id: ID!
firstName: String!
lastName: String!
}
type UserPrivate implements User {
id: ID!
firstName: String!
lastName: String!
email: String!
phone: String!
bookings: [Booking!]
}
- Apollo Contracts
type Query {
userById(id: Int!): User
}
type User {
id: ID!
firstName: String!
lastName: String!
email: String! @tag(name: "internal")
phone: String! @tag(name: "internal")
bookings: [Booking!] @tag(name: "internal")
}
My Thoughts:
- Apollo Contracts looks good, but it’s only available in an enterprise plan, so It would be our last option.
- (1) separate private fields in one field: looks easy to implement and to add the authorization rules to just the
private
field.
How are others doing? I would like to hear your opinion.
Thanks,