GraphQL

Queries

for each service generated, it already available on the gql docs. The basic functionality are (for example we have post service):

Read

list of posts

query{
    posts {
      id
      text
      
      #Default generated fields
      createdAt
      updatedAt
      createdBy {
        id
        firstName
      }
      updatedBy {
        id
        firstName
      }
   }
 }

Connection

list of posts with aggregate and pagination info

  query {
      postsConnection {
          data {
              id
              text
          }
          total
          limit
          skip       
      }
 }

Detail

post detail

query {
       post (id: "5d73013deefb420523f31ae0") {
        id
        text
      }
 }

Querying

list query with params

  query {
      posts (
          where:{
          	text_contains: "a",
            createdBy: {
              email: "radiegtya@gmail.com"
            },
            createdAt_lt: "2019-10-24"
          },
          limit: 10,
          skip: 5,
          orderBy: createdAt_ASC
      ) {
          id
          text
      }
  }    

more queries documentation, COMING SOON (for now refer to the autocomplete feature in playground)

Raw Query

list query with params with Raw Query. It means that you can use feathers mongo native query.

  query posts ($query: JSON){
      posts (query: $query) {
          id
          text
      }
  }    

  #variables
  {
      "query": {
          "$limit": 10,            
          "$skip": 1,
          "text": {
              "$regex": "post 1",
              "$options": "i",
          },              
      }
  }

more queries are available on feathers docs (https://docs.feathersjs.com/api/databases/querying.html#limit)

Mutations

Create

create a post

mutation {
  createPost (input: {
      text: "Post 1"
  }) {
      id
      text
  }
}

Update

update a post

mutation {
  updatePost (id: "5d73013deefb420523f31ae0", input: {
      text: "Post 1"
  }) {
      id
      text
  }
}

Delete

delete a post

mutation {
  deletePost (id: "5d73013deefb420523f31ae0") {
      id
      text
  }
}

One to Many

Create and Connect

create a Comment on a Post

mutation {
  createComment (input: {
      text: "Comment 1"
      postId: "5da9edc37e23d04ae427f4b5"
  }) {
      id
      text
  }
}

Read with Relations

list of posts with comments. Post hasMany Comment, and Comment belongsTo Post.

query {
  posts {
      id
      text
      comments {
          id
          text
      }
  }
}

Many to Many

Create and Create Many Relation

create a Post and create new multiple categories

mutation {
  createPost (input: {
      text: "Post 1"
      categories: [
           {name: "Category 1"},
           {name: "Category 2"}
      ]
  }) {
      id
      text
      categories {
          id
          name
      }    
  }
}

Create and Connect Many Relation

create a Post and connect with multiple existing categories

mutation {
  createPost (input: {
      text: "Post 2"
      categoriesIds: ["5da9edc35f9a844ae7b09843", "5da9edc35f9a844ae7b09844"]
  }) {
      id
      text
      categories {
          id
          name
      }    
  }
}

Update and Create Many

update a Post and create new multiple categories (replace old data with new data)

mutation {
  updatePost (id: "5dad883e700c934db8a1ad21", input: {
      text: "Post 1"
      categories: [
           {name: "Category 1"},
           {name: "Category 2"}
      ]
  }) {
      id
      text
      categories {
          id
          name
      }    
  }
}

Update and Replace Many

update a Post and connect+replace existing multiple categories

mutation {
  updatePost (id: "5dad883e700c934db8a1ad21", input: {
      text: "Post 1"
      categoriesIds: ["5da9edc35f9a844ae7b09843", "5da9edc35f9a844ae7b09844"]
  }) {
      id
      text
      categories {
          id
          name
      }    
  }
}

Remove Relation

remove an existing category on a post

mutation {
  removeCategoryOnPost(categoryId: "5dad88399f256d4db947c4fa", postId: "5dad883e700c934db8a1ad21"){
    id
    text
    categories{
      id
      name
    }
  }
}

Add Relation to Existing

add existing category on existing post

mutation {
  addCategoryOnPost(postId: "5dad87a4700c934db8a1ad1e", categoryId: "5dad88309f256d4db947c4f9"){
    id
    text
    categories{
      id
      name
    }
  }
}

Authentication and Users GQL

because User services are generated by default, You also have ability to do basic functionality for this service, such as CRUDSS and Authentication:

Queries

  • lists: list of users

      users {
          id
          email    
      }
  • connection: list of users with aggregate and pagination info

      usersConnection {
          data {
              id
              text
          }
          total
          limit
          skip       
      }
  • detail: user detail

      user (id : "5d73013deefb420523f31ae0") {
          id
          email
          firstName
          lastName
      }

Mutations

  • login: authenticate a user, and return a token and user obj

      login (input: {
          email: "someone@microgen.com"
          password: "secret"
      }) {
          user {
              id
              email
          }
          token
      }
  • register: register a user, and return a token and user obj

      # Note: the first user registered on microgen, by default had admin role
      register (input: {
          email: "someone@microgen.com"
          password: "secret"
          firstName: "someone"
          role: WRITER #optional, and the value can only be authenticated or the same level as described on enum Role. The default value is authenticated.
      }) {
          user {
              id
              email
              firstName
          }
          token
      }
  • verifyEmail: send email to user, when they are registering as new user

      verifyEmail (input: {
          token: "token-from-email-link-params"
      }) {
          message
      }
  • forgetPassword: send email to user, when they are forgetting their password

      forgetPassword (input: {
          email: "someone@microgen.com"
      }) {
          message
      }
  • resetPassword: resetting an user password, and sending them email

      resetPassword (input: {
          newPassword: "newSecret"
          token: "user-someone-current-token"
      }) {
          message
      }
  • changeProfile: update a user (authenticated user, and its own data)

      changeProfile (id: "5d73013deefb420523f31ae0", input: {
          firstName: "Lucinta"
          lastName: "Luna"
      }) {
          user {
              id
              firstName
          }        
      }
  • createUser: create a user (admin only)

      createUser (input: {
          email : "someuser@microgen.com"
          password: "secret"
          firstName: "someuser"
          role: ADMIN #required, and the value can be anything as described on enum Role
      }) {
          user {
              id
              email
          }
          token
      }
  • updateUser: update a user (admin only)

      updateUser (id: "5d73013deefb420523f31ae0", input: {
          firstName: "Lucinta"
          lastName: "Luna"
      }) {
          user {
              id
              firstName
          }        
      }
  • deleteUser: delete a user (admin only)

      deleteUser (id: "5d73013deefb420523f31ae0") {
          user {
              id
              email
          }
      }

Socket

Microgen is battery included, socket is one of them. To use it, simply use graphql subscription tag. There are 3 types of subscriptions (for example You have post service, it will generate):

  • postAdded: triggered when post added

      subscription {
          postAdded {
              id
              text
          }
      }
  • postUpdated: triggered when post updated

      subscription {
          postUpdated {
              id
              text
          }
      }
  • postDeleted: triggered when post deleted

      subscription {
          postDeleted {
              id
              text
          }
      }

Role & Permissions

Microgen had already defined role & permissions for You. To change the default permissions, You can change on "outputs/services/users/permission.js". But as we knew before, change something on outputs folder is not the best practice. Instead, You can change the permission, inside "hooks/user.js" by rewriting the permissions object (more info: https://docs.mejik.id/mejik-microgen/hooks#usage-example-on-user-service-with-custom-permissions).

const permissions = {
    admin: ['admin:*'],
    authenticated: [
        'post:find', 'post:get', 'post:create', 'post:updateOwn', 'post:removeOwn', 'post:patch',
    ],
    public: [
        'post:find', 'post:get',
    ],
}
module.exports = {
    permissions
}

on the example above, it means that:

  • admin able to access everything

  • authenticated users, able to do everything on post-service (special case for update and delete only able to update and delete owned data)

  • public (unauthenticated users) only able to use post-service on find and get methods

Anyways if you remember that you had set enum Role with custom input, then you will have some permissions added.

# Custom Permission

const permissions = {
    admin: ['admin:*'],
    authenticated: [
        'post:find', 'post:get', 'post:create', 'post:updateOwn', 'post:removeOwn', 'post:patch',
    ],
    editor: ['admin:*'],
    writer: [
        'post:find', 'post:get', 'post:create', 'post:updateOwn', 'post:removeOwn', 'post:patch',
    ],
    public: [
        'post:find', 'post:get',
    ],
}
module.exports = {
    permissions
}

Note: the first user registered on microgen, are registered as admin role

Add-ons

Microgen comes with a bunch of Add-ons functionality such as email, file storage, push notification, and social media auth. In order to use them, you must set the API KEY, API SECRET etc from third parties provider such as Google Auth, OneSignal, SendGrid, and AWS S3. If you don't want to setup them, you can use Microgen default setup (only available on PRO and Enterprise Pricing Plan).

OTP

You can using OTP verification in microgen, but first don't forget to set the configuration at the setting menu first, because we don't provide OTP SMS provider. Here is some queries that you can use:

  • loginWithPhone: to login using phone number and send SMS to a number, it will also check whether there is a user with same phone number or not

    mutation{
      loginWithPhone(input: {
        phoneNumber: "+6285641278479"
      }){
        message
      }
    }
  • verifyLoginWithPhone: to verify the number that had been sent after using loginWithPhone mutation. This mutation response is a token that can be used to logged in your user.

    mutation{
      verifyLoginWithPhone(input: {
        phoneNumber: "+6285641278479"
        code: "OTP_THAT_ALREADY_SENT"
      }){
        token
      }
    }
  • requestOtp: to request an OTP in any flexible situation. For example completing user profile.

    mutation {
      requestOtp(input: {
        phoneNumber: "+6285641278479"
      }){
        message
      }
    }
  • verifyOtp: to verify OTP that had been sent using requestOTP mutation. This will not check user table, and not sent back token

    mutation {
      verifyOtp(input: {
        phoneNumber:"+6285641278479"
        code: "OTP_THAT_ALREADY_SENT"
      }){
        message
      }
    }

Email

Email functionality by default are attached to another service such as forgetPassword, register, etc. But if you want use it as standalone, you should loggedIn as "admin" role, then execute some of these mutation below:

mutation

  • sendEmail: Sending email to any email(s)

      mutation {
          sendEmail(input:{
              to:"someone@gmail.com;anotherone@gmail.com"
              body:"hahaha"
              subject: "test"
          }){
              message
          }
      }
  • sendEmailToUsers: Sending email to all registered users

      mutation {
          sendEmailToUsers(input:{            
              body:"hahaha"
              subject: "test"
          }){
              message
          }
      }

Files Storage

  • Upload file(s) to storage. (in this example, we use service called image)

      mutation {
          createImage(input:{
              name: "an Image"
              url: **Upload Scalar**
          }){
              url
          }
      }

    note that createImage mutation is returning an url, this url String can be used to be saved on your related service as a file path.

Push Notification

  • Subscribe playerId (a device) to receive all push notification

      mutation {
          subscribePushNotificatiton(input:{
              playerId: "cde97568-d73e-4daf-97e6-18f5d869deba"
          }){
              message
          }
      }
  • Subscribe playerId (a device) to receive push notification on a segment

      mutation {
          subscribePushNotificatiton(input:{
              playerId: "cde97568-d73e-4daf-97e6-18f5d869deba"
              segment: "room-1"
          }){
              message
          }
      }
  • Send push notification to all

      mutation{
          sendPushNotification(input:{
              contents:"Testing cuk 123"
          }){
              message
          }
      }
  • Send push notification to all players on a segment

      mutation {
          sendPushNotificationBySegment(input:{
              contents:"testing by segment"
          }, segment: "room-1"){
              message
          }
      }
  • Send push notification to specific userId (in all of his devices/playerIds). UserId here is the real id that registered on database, and not playerId.

      mutation {
          sendPushNotificationByUserId(input:{
              contents:"testing by segment"
          }, userId: "5d84d7038a65db26a8633701"){
              message
          }
      }
  • Unsubscribe playerId (device) from all push notifications

      mutation {
          unsubscribePushNotification(input:{
              playerId: "cde97568-d73e-4daf-97e6-18f5d869deba"
          }){
              message
          }
      }
  • Unsubscribe playerId (device) on receiving push notification from a segment

      mutation {
          unsubscribePushNotification(input:{
              playerId: "cde97568-d73e-4daf-97e6-18f5d869deba"
              segment: "room-1"
          }){
              message
          }
      }

Social Media Auth

  • Login with Google Account (jwtToken are received when a dialog closed, search about google login third party at client side)

      mutation {
          loginWithGoogle(input: {
              jwtToken: "cde97568d73e-4daf-97e6-18f5d869deba"
          }){
              token
              user {
                  id
                  email
              }
          }
      }
  • Login with Facebook Account (jwtToken are received when a dialog closed, search about facebook login third party at client side)

      mutation {
          loginWithFacebook(input: {
              jwtToken: "cde97568d73e-4daf-97e6-18f5d869deba"
          }){
              token
              user {
                  id
                  email
              }
          }
      }

Last updated