Skip to content

A full server example with Pioneer, Vapor, Graphiti, and Fluent

License

Notifications You must be signed in to change notification settings

d-exclaimation/pioneer-example

Repository files navigation

Pioneer Server Example

An example of a GraphQL server built with Pioneer.

This server provide a chat service which includes:

  • Ability to sign up / log in user
  • Ability to create / open rooms, if authenticated
  • Ability to write messages into a room, if authenticated
  • Ability to listen to messages given sent to a room, if authenticated
  • Authentication through JWT
  • Usage of GraphQL Union for better error or result handling on mutations

Technologies

  • Swift for Programming Language
  • GraphQL for API Language
  • Vapor for Web framework
  • Graphiti for GraphQL schema library
  • Pioneer for GraphQL server library
  • PostgreSQL for RDMS
  • Fluent for ORM

Operations

Queries

me.graphql Check if the request is logged in as a user or not
query Me {
  me {
    id
    name
    messages {
      ...
    }
  }
}

Return a full User if logged in or null if not.

users.graphql List all users in the database
query Users {
  users {
    id
    name
    messages {
      ...
    }
  }
}
rooms.graphql List all rooms in the database
query Rooms {
  rooms {
    id
    history {
      ...
    }
    users {
      ...
    }
  }
}

Mutations

signup.graphql

Sign up / create a user, and log in as that user

mutation Signup($name: String!) {
  signup(name: $name) {
    __typename
    ... on InvalidName {
      name
    }
    ... on LoggedUser {
      token
      user {
        ...
      }
    }
  }
}

Results:

  • InvalidName
    • Returned when the name is not valid name for the database
  • LoggedUser
    • Returned when a successful sign up happen and both user and its token have been created
login.graphql

Log into a user

mutation Login($name: String!) {
  login(name: $name) {
    __typename
    ... on InvalidName {
      name
    }
    ... on LoggedUser {
      token
      user {
        ...
      }
    }
  }
}

Results:

  • InvalidName
    • Returned when the name is not valid / not in database
  • LoggedUser
    • Returned when a successful login happen and a token has been created
open.graphql

Open a room

mutation Open {
  open {
    __typename
    ... on Unauthorized {
      operation
    }
    ... on NewRoom {
      room {
        id
        history {
          ...
        }
        users {
          ...
        }
      }
    }
  }
}

Must be logged in / Have valid token in Authorization header

Results:

  • Unauthorized
    • Returned when not logged in as a user
  • NewRoom
    • Returned when a room has been created
write.graphql

Write a new message to a user

mutation Write($content: String!, $to: ID!) {
  write(content: $content, to: $to) {
    __typename
    ... on Unauthorized {
      operation
    }
    ... on InvalidRoom {
      roomId
    }
    ... on NewMessage {
      message {
        id
        createdAt
        content
        author {
          ...
        }
        room {
          ...
        }
      }
    }
  }
}

Must be logged in / Have valid token in Authorization header

Results:

  • Unauthorized
    • Returned when not logged in as a user
  • InvalidRoom
    • Returned when the to parameter is not a valid Room id
  • NewMessage
    • Returned when message successfully created and shared to all listener for the room

Subscriptions

listen.graphql

Listen to all message sent to a room

subscription Listen($to: ID!) {
  listen(to: $to) {
    content
    createdAt
    id
    author {
      ...
    }
    room {
      ...
    }
  }
}

Subscription must go through WebSocket which also require authentication

Results will be sent back when a message were created and sent to the room specified in the to parameter

Schema

schema.graphql
"""Results from sign up and log in"""
union AuthResult = InvalidName | LoggedUser

"""A result given an incorrect name"""
type InvalidName {
  """The name in question"""
  name: String!
}

"""A result given when Room id is invalid"""
type InvalidRoom {
  """The ID in question"""
  roomId: ID!
}

"""A result with all the information of a Logged in User"""
type LoggedUser {
  """JWT token for this User"""
  token: String!

  """The User for this logged in result"""
  user: User!
}

"""A Message sent to a room by a user"""
type Message {
  """User who wrote this Message"""
  author: User!

  """Message textual content"""
  content: String!

  """Message creation date and time"""
  createdAt: String!

  """Message unique identifier"""
  id: ID!

  """Room where this Message is sent to"""
  room: Room!
}

type Mutation {
  """Log into an exisiting User"""
  login(
    """Name of the User"""
    name: String!
  ): AuthResult!

  """Open a Room (must be logged in)"""
  open: OpenResult!

  """Sign up a new User"""
  signup(
    """Name of the User"""
    name: String!
  ): AuthResult!

  """Write a Message to a Room (must be logged in)"""
  write(
    """The content of the Message"""
    content: String!

    """The Room id sent the Message to"""
    to: ID!
  ): WriteResult!
}

"""A result given a successful write operation"""
type NewMessage {
  """The Message written"""
  message: Message!
}

"""A result given a successful open operation"""
type NewRoom {
  """The Room opened"""
  room: Room!
}

"""Results from opening a room"""
union OpenResult = Unauthorized | NewRoom

type Query {
  """Check for the sign in status"""
  me: User

  """List all available Rooms"""
  rooms: [Room!]!

  """List all signed up Users"""
  users: [User!]!
}

"""A certain Room / channel of messages"""
type Room {
  """Message history for this Room sent by any User"""
  history: Message!

  """Room unique identifier"""
  id: ID!

  """Users who have written into this Room"""
  users: User!
}

type Subscription {
  """Listen to all Messages sent to a Room (must be logged in)"""
  listen(
    """The Room id to listen to"""
    to: ID!
  ): Message!
}

"""A result given when not logged in"""
type Unauthorized {
  """Name of operation being performed"""
  operation: String!
}

"""A User who can write down messages"""
type User {
  """User unique identifier"""
  id: ID!

  """Message written by this User sent to any Room"""
  messages: Message!

  """User public name"""
  name: String!
}

"""Results from writing a message"""
union WriteResult = Unauthorized | InvalidRoom | NewMessage

About

A full server example with Pioneer, Vapor, Graphiti, and Fluent

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published