Skip to content

Instantly share code, notes, and snippets.

@amonks
Last active August 21, 2018 18:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amonks/989c815eca601d7ae63ded8fa5f9d530 to your computer and use it in GitHub Desktop.
Save amonks/989c815eca601d7ae63ded8fa5f9d530 to your computer and use it in GitHub Desktop.
actor—object system with permissions in two graphql interfaces
##############################################################
# #
# GRAPHQL SCHEMA EXAMPLE #
# actor-object system with permissions #
# #
##############################################################
# #
# Andrew Monks #
# 05/15/2017 #
# #
# This document describes how an Actor and Object interface #
# can be used to implement a simple, extensible permissions- #
# -and-ownership model across disparate types within an #
# application. #
# #
# I'm not sure if this is the best approach. Don't take it #
# as advice. #
# #
# First, I'll show the two interfaces: Actor and Object. #
# Then, I'll provide a couple concrete implementations of #
# both interfaces. #
# #
##############################################################
## Actor
#
# Actor is our basic "agent that can do stuff" interface.
#
# Users and organizations implement Actor.
interface Actor {
# Every Actor gets a namespace.
# (think https://github.com/[namespace]/[object])
namespace: String! @isUnique
# Actors can own Objects
objects: [Object!]! @relation(name: "ActorOnObject")
# Every Object has a set of Actors who can see it.
canSee: [Object!]! @relation(name: "ViewersOnObject")
}
## Object
#
# Everything that _can't_ do stuff is an Object.
#
# Every Object has permissions and is owned by an Actor.
interface Object {
# Every Object is owned by an Actor--typically its creator
# Different Object types might come with their own set of
# relations (eg. a tour has itineraries), but the Object
# interface only mandates a single-Actor owner.
owner: Actor @relation(name: "ActorOnObject")
# Every Object has a set of Actors who can see it.
visibleTo: [Actor!]! @relation(name: "ViewersOnObject")
# Any Object can have Comments attached to it.
comments: [Comment!]! @relation(name: "CommentOnParent")
}
############################################################
## Post
#
# A Post is an Object.
#
# Posts (like all Objects) can have Comments on them.
type Post implements Node, Object {
# A Post has a title
title: String!
# A Post has a body
body: String!
# implements Node
id: ID! @isUnique
# implements Object
objectType: "Post"
owner: Actor @relation(name: "ActorOnObject")
visibleTo: [Actor!]! @relation(name: "ViewersOnObject")
comments: [Comment!]! @relation(name: "CommentOnParent")
}
## Comment
#
# Every Object (including Comments) can have Comments on it.
#
# Like all Objects, Comments have a set of actors who are
# permitted to see them.
type Comment implements Node, Object {
# A Comment is commenting _on_ some other Object
# (maybe even another Comment)
parent: Object @relation(name: "CommentOnParent")
# A Comment has text
text: String!
# implements Node
id: ID! @isUnique
# implements Object
objectType: "Comment"
owner: Actor @relation(name: "ActorOnObject")
visibleTo: [Actor!]! @relation(name: "ViewersOnObject")
comments: [Comment!]! @relation(name: "CommentOnParent")
}
## User
#
# A User is the basic type of Actor.
#
# Like all Actors, Users can own Objects.
type User implements Node, Actor {
# A User can be a member of multiple Organizations.
organizations: [Organization!]! @relation(name: "UsersOnOrganization")
# implements Node
id: ID! @isUnique
# implements Actor
namespace: String! @isUnique
objects: [Object!]! @relation(name: "ActorOnObject")
canSee: [Object!]! @relation(name: "ViewersOnObject")
}
## Organization
#
# Organizations are the other type implementing Actor.
#
# Like all Actors, Users can own Objects.
type Organization implements Node, Actor {
# Organizations have members which are Users.
members: [User!]! @relation(name: "UsersOnOrganization")
# implements Node
id: ID! @isUnique
# implements Actor
namespace: String! @isUnique
objects: [Object!]! @relation(name: "ActorOnObject")
canSee: [Object!]! @relation(name: "ViewersOnObject")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment