Skip to content

tylerkneidl/MONARQ

 
 

Repository files navigation

MONARQ

MONARQ makes it easy to accept REST requests with an existing Express/GraphQL server. Expand your application's API compatability with just a few lines of code.

Contents

Installation
How It Works
Required User Inputs
Getting Started
Keep in Mind

Installation

Install MONARQ through the command line

npm install monarq

Now the two core functions of the package can be imported into your main Express/GraphQL server.

import { queryMap, routerCreation } from 'monarq';

How It Works

There are two functions that need to be invoked within your main Express/GraphQL server file.

Step 1:

queryMap generates an object containing GraphQL queries/mutations and arguments for each operation specified in the Manifest Object. This 'map' of queries will be used to match REST requests to corresponding GQL operations. queryMap takes up to three arguments:

  • Manifest Object
  • Schema of type GQLSchema object
  • (Optional) Array containing any custom scalar types declared in your schema

Invoke this function in your main Express/GraphQL server file and assign the result to a constant.

Examples

If no custom scalar types are used:

const createdQuery = queryMap(manifest, schema);

OR

If a custom scalar type of 'Date' is defined in the schema:

const createdQuery = queryMap(manifest, schema, ['Date']); 

Step 2:

routerCreation returns an express.Router instance containing route handlers for each of the API Paths defined within the Manifest Object. routerCreation takes three arguments:

  • Manifest Object
  • createdQuery (the saved value from invoking the queryMap function)
  • An Object with three keys: schema, context, and your created executeFn

Example

const routes = routerCreation(manifest, createdQuery, {
  schema,
  context,
  executeFn,
});

Step 3:

Implement the newly created router with app.use in your server file. All REST requests should be directed to the same top-level path (e.g., '/rest') so that the routes middleware will be applied.

Example

app.use('/rest', routes);

That's it! Your application is now ready to accept both GraphQL and REST requests.

Required User Inputs

Before implementing queryMap and routerCreation, you will have to define the REST endpoints that you want to expose. Each REST endpoint will be mapped to a GraphQL operation, thus allowing the client to send REST requests and you to handle those requests with your GraphQL server. MONARQ gives you the flexibility to define as many or as few REST endpoints as you want to expose.

Create a manifest object in a file and import into your server file. You can also visit MONARQ's website to create the manifest object using a simple visual interface.

1) DEFINE MANIFEST OBJECT

The Manifest Object must be in a specific format as shown in the following example:

const manifest = {
  endpoints: {
    '/book/:id': {
      get: {
        operation: 'getBook',
      },
    },
    '/books': {
      post: {
        operation: 'createBook',
      },
    },
    '/authors': {
      post: {
        operation: 'createAuthor',
      },
    },
  },
};

This Manifest Object is a required input into both queryMap and routerCreation. Each manifest object will contain:

  • A key called endpoints, with value object
  • The endpoints object will have all the REST API Paths you want to expose as the keys with the value of an object
    • Remember to have clients pre-pend these paths with whatever top-level path was defined in your route handler when making requests (e.g., '/rest/books')
  • Inside each REST API Path object, the keys will have one of these five labels: GET, POST, PUT, PATCH, DELETE. These methods correspond with the HTTP method that you want the client to send the request as.
  • Inside each HTTP method object, a required key operation will have the value of a string that corresponds to the GraphQL Query or Mutation operation name that should be invoked when the REST endpoint is requested. Note: the operation must be present within the GraphQL schema.
    • Optional: if the operation requires arguments and default parameters have been defined, you must specify these within an object at key defaultParams, also within the HTTP method object

Excerpt of an example schema corresponding to the the manifest object above:

type Query {
  books(pageSize: Int!, page: Int!): Books!
  book(id: ID!): Book
}

type Mutation {
  updateBook(id: ID!, book: BookUpdateInput!): Book!
}

2) DEFINE EXECUTE FUNCTION

One of the required arguments for routerCreation is a standardized form of the method that your server uses to execute GraphQL queries. Create a wrapper function labeled executeFn that accepts one argument, an object, with four keys: query, context, schema, and variables. Have the wrapper function return the response from the GraphQL server.

Example

In this case, the native graphql method from graphql.js is used to execute queries.

async function executeFn({ query, variables, schema, context, }) {
    const data = await graphql(schema, query, null, context, variables);

    return data || errors;
}

3) IMPORT

Lastly, make sure the main Express/GraphQL server file has your GQL schema and context imported in.

Getting Started

Check out the Example folder within the MONARQ repository to see a simple implementation of the package.

Keep in Mind

+ If default parameters exist in the resolvers, make sure to add the key defaultParams with the value of an object with the keys as the variable names and the value of the default value the resolver uses. See the above example Manifest Object for more details.

+ GraphQL Subscription Type is not supported at this time.

+ MONARQ currently supports the 5 main HTTP REST Methods (Get, Post, Put, Patch, Delete). Any other method passed in will throw an error.

Contributors

Peter Baniuszewicz @Peter-Ba

Amy Chen @designal46

Tyler Kneidl @tylerkneidl

Helen Regula @helenregula

Visit the MONARQ website for more information

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 100.0%