Bicycle

Bicycle

  • Docs
  • Blog

›JavaScript Reference

Getting Started

  • Intro
  • JavaScript
  • TypeScript

JavaScript Reference

  • Schema
  • Server

BicycleServer

If you have a schema defined as JavaScript files in the recommended structure, you can construct a bicycle server instance like:

import BicycleServer from 'bicycle/server';

const options = {};

const bicycle = new BicycleServer(__dirname + '/bicycle-schema', options);

Bicycle will automatically require the js files for you. If you prefer, you can explicitly import them and pass them to BicycleServer

import BicycleServer from 'bicycle/server';
import Root from './bicycle-schema/objects/Root';
import Todo from './bicycle-schema/objects/Todo';
import id from './bicycle-schema/scalars/id';

const options = {};

const bicycle = new BicycleServer({
  objects: [Root, Todo],
  scalars: [id],
}, options);

options

NameTypeDescription
disableDefaultLogging
boolean

silence error logging

@default false

onError
(e: {error: Error}) => any

Event triggered when an error is thrown by a mutaiton or query resolver

@default no-op

onMutationEnd
(
  e: {
    mutation: {
      readonly method: string;
      readonly args: Object;
    };
    result: MutationResult;
  },
) => any

Event triggered when a mutation ends

@default no-op

onMutationStart
(
  e: {
    mutation: {
      readonly method: string;
      readonly args: Object;
    };
  },
) => any

Event triggered when a mutation starts

@default no-op

onQueryEnd
(
  e: {
    query: Object;
    cacheResult: Object;
  },
) => any

Event triggered when a query ends

@default no-op

onQueryStart
(e: {query: Object}) => any

Event triggered when a query starts

@default no-op

onRequestEnd
(
  e: {
    readonly request: BicycleRequest;
    readonly response: ServerResponse;
  },
) => any

Event triggered when a request ends

@default no-op

onRequestStart
(
  e: {readonly request: BicycleRequest},
) => any

Event triggered when a request starts

@default no-op

sessionStore
SessionStore

a custom session store

@default MemorySessionStore

sessionStoreSize
number

The maximum number of active sessions.

You can also set via the BICYCLE_SESSION_STORE_SIZE environment variable.

@defualt 100

createMiddleware

Once you have a schema, you can expose it on a path using createMiddleware. By default this responds to messages sent as a JSON body in an http POST. Conveniently, this is what the default NetworkLayer implementation does too.

import express from 'express';

const app = express();

app.use('/bicycle', bicycle.createMiddleware(req => ({user: req.user})));

app.listen(process.env.PORT || 3000);

I recommend serving it on the path /bicycle as this is the default, but you can pass options to NetworkLayer, when constructing the client to select a different path if you want.

args

  • getContext - A function that takes a request and returns the "context" object used for queries and mutations

createServerRenderer

If you want your application to render on the server side (e.g. for users without JavaScript enabled) you can use createServerRenderer

import BicycleServer from 'bicycle/server';

const schema = __dirname + '/schema';
const options = {};
const bicycle = new BicycleServer(schema, options);

const serverRenderer = bicycle.createServerRenderer((client, ...args) => {
  // you can render your app here, querying from "client"
  // your app will be rendered multiple times until all the data has been loaded
  // only `client.queryCache` is implemented.
  const {result, loaded, errors} = client.queryCache({{todos: {id: true, title: true, completed: true}}});
  if (loaded && !errors.length) {
    return renderTemplate(result);
  }
});

// the first argument is the "context", subsequent arguments are passed through to your rendering function.
serverRenderer({user: 'my user'}, ...args).done(({serverPreparation, result}) => {
  console.log('server renderer result:');
  console.log(result);
  // serverPreparation can be used to rehydrate the data on the client
});

runQuery

If you need to run a query on the server side, you can directly call runQuery. You will need to pass it a context.

const result = await bicycle.runQuery({
  todos: {id: true, title: true, completed: true},
}, context)
console.log(result.todos);

runMutation

If you need to run a mutation on the server side, you can directly call runMutation. You will need to pass it a context.

await bicycle.runMutation('Todo.toggle', {id, checked: true}, context);
console.log('Todo complete');

handleMessage

If you've replaced the network layer with a custom network layer (only for really advanced use cases) you can use handleMessage instead of createBicycleMiddleware.

import BicycleServer from 'bicycle/server';

const schema = __dirname + '/schema';
const options = {};
const bicycle = new BicycleServer(schema, options);

class MockNetworkLayer {
  constructor(bicycle, context) {
    this._bicycle = bicycle;
    this._context = context;
  }
  send(message) {
    return this._bicycle.handleMessage(message, this._context);
  }
}

getActiveSessionCount

Returns the number of active sessions in the session store, if the session store supports this method:

const activeSessionCount = bicycle.getActiveSessionCount();

getMaxSessionCount

Return the maximum number of active sessions in the session store, if the session store supports this method. Note that the default Memory session store discards half of the sessions when this maximum is reached, rather than discarding essions one at a time.

const usage = `${(bicycle.getActiveSessionCount() / bicycle.getMaxSessionCount()) * 100}%`;
← Schema
  • options
  • createMiddleware
    • args
  • createServerRenderer
  • runQuery
  • runMutation
  • handleMessage
  • getActiveSessionCount
  • getMaxSessionCount
Bicycle
Docs
Getting StartedAPI Reference (JavaScript)
More
BlogGitHubStar
Copyright © 2020 ForbesLindesay