UNPKG

@nzz/q-server

Version:

**Maintainer**: [Franco Gervasi](https://github.com/fgervasi)

161 lines (135 loc) 6.33 kB
--- title: Developing Tools --- A __Q tool__ is a HTTP service providing an API to get rendering information for a given dataset. ## Q cli With Q cli you can easily setup new tools and test them with Q dev server which is a Q server light offering the relevant routes for rendering info. ### Installation The cli tool is an npm package and can be installed by running ```bash $ npm install -g @nzz/q-cli ``` ### Usage Once you've installed Q cli you can bootstrap a new tool by running ```bash $ Q new-tool new-tool-name ``` while 'new-tool-name' is the name of the tool you are creating. To get a list of all available command options you can run ```bash $ Q new-tool --help ``` Now you are ready to rumble, i.e. you can change the schema in `/resources/schema.json` and the rendering in `/rendering-info/web.js`. You can get an overview about the tool routes below in the section API entpoints. To see how the rendering infomation for a tool is being displayed you can start a Q dev server by running ```bash $ Q server ``` The tool itself has to be started too to be able to see anything. To get a list of all available command options you can run ```bash $ Q server --help ``` Further informationen can be found on [GitHub](https://github.com/nzzdev/Q-cli). ## API Endpoints One endpoint to return the tool specific JSON schema is mandatory as it's used by Q editor for rendering and validation of the respective form: - __GET__ _/schema.json_ Additionally you can specify an endpoint to get rendering information for a given Q item. See [Rendering Info?](rendering-info.html) for detailed information about what we mean with that term. The exact endpoint path is variable and specified in _config/tools.js_ of your Q server implementation for each tool and target individually. The path may be meaningful in the sense of what will be returned. So far, we make use of the following two endpoints: - __POST__ _/rendering-info/html-static_: returns static rendering information, like markup and optional stylesheets - __POST__ _/rendering-info/html-js_: returns rendering information that contains client side scripts among markup and optional styleheets Example for a basic html-static route: ```javascript module.exports = { method: 'POST', path: '/rendering-info/html-static', options: { validate: { options: { allowUnknown: true }, payload: { // item gets validated against given schema item: schema, // true if item was read from database, false if not (useful if you want to use the appendItemToPayload query from Q servers tool-default route) itemStateInDb: Joi.boolean(), // one can pass further runtime configuration toolRuntimeConfig: Joi.object() } }, cors: true }, handler: async function(request, h) { let data = { stylesheets: [ { // name of stylesheet will be used to call the correct stylesheet endpoint to load css // one can also specify a url instead which will result in loading css directly from that url name: 'default' } ], // pass the data object to svelte render function to get markup markup: staticTemplate.render(request.payload.item) } return data; } } ``` As explained in _on name and path_ on [Rendering Info?](rendering-info.html) we'll need additional endpoints if a tool requires stylesheets or scripts to load: - __GET__ _/stylesheet/{name*}_: returns the stylesheet according to the given name. In our examples we use Sass for styling and return rendered css. Typically the handler method is the same for each stylesheet name, hence we just need one endpoint with the name as path parameter, like specified in our [Q renderer skeleton](https://github.com/nzzdev/Q-renderer-skeleton/blob/master/routes/stylesheet.js): ```javascript module.exports = { method: 'GET', path: '/stylesheet/{name*}.css', handler: async function(request, h) { // return the stylesheet content } } ``` - __GET__ _/script/{name*}_: returns the script according to the given name. ```javascript module.exports = { method: 'GET', path: '/script/{name*}.js', handler: function(request, reply) { // return the script content } } ``` ## Docker We deploy each tool as a Docker container in our environment. See [Docker documentation](https://docs.docker.com/) to get familiar with Docker. Our Dockerfiles do have a simple structure which is the same for each tool: ```sh # Use following version of Node as the base image FROM node:9 # Set work directory for run/cmd WORKDIR /app # Copy package.json into work directory and install dependencies COPY package.json /app/package.json RUN npm install # Copy everthing else in work directory COPY . /app # Run node CMD ["node", "/app/index.js"] ``` All docker containers are publicly available on [Docker Hub](https://hub.docker.com/), just search for our organization _nzzonline_ to get the container list. We use Rancher to host our containers. See [Rancher Website](https://rancher.com/) or [Rancher documentation](https://docs.rancher.com) for more information. You can setup your whole environment differently and without Docker of course. ## Travis [Travis](https://travis-ci.com/) is our continious integration service of choice. If you want to learn how to set it up, consult the [Travis documentation](https://docs.travis-ci.com/). The build includes execution of tests, creation and push of the docker container to docker hub as well as, if the current branch is staging, the automatic upgrade of the docker container in Rancher. ```yml dist: trusty sudo: true services: - docker language: node_js node_js: - '8' install: - npm install before_script: - DOCKER_IMAGE_NAME="q-renderer-skeleton" - DOCKER_TAG=$TRAVIS_BRANCH script: - npm test - docker build -t $DOCKER_IMAGE_NAME:$DOCKER_TAG . - echo $DOCKER_PASSWORD | docker login -u="$DOCKER_USERNAME" --password-stdin; docker tag $DOCKER_IMAGE_NAME:$DOCKER_TAG nzzonline/$DOCKER_IMAGE_NAME:$DOCKER_TAG; docker push nzzonline/$DOCKER_IMAGE_NAME:$DOCKER_TAG; cache: directories: - node_modules ```