Blueprint
  • Blueprint Developer Guide
  • Quick Start
    • Getting Started
    • My First Application
      • Creating Your Application
      • Controllers
      • Routers & Routes
      • Services
      • Resources & Resource Controllers
      • Validating & Sanitizing Input
      • Unit Testing Your Application
      • Policies
  • Developer Guide
    • The Object Model
      • Introduction
      • Classes and Instances
      • Computed Properties
      • Aggregated Properties
      • Mixins
    • Routers and Controllers
      • Introduction
      • Routers
      • Controllers
      • Resources
    • Models
    • The Server
    • Policy Framework
    • Services
    • Messaging Framework
    • Configuration Management
    • Application and Resources
      • Lookup Operation
      • Views
      • Assets
    • Blueprint Modules
    • Blueprint Cluster
      • What is a Blueprint Cluster?
      • Running a Blueprint Cluster
      • Technical Details
    • Testing Framework
    • Command-line Interface (Coming Soon)
Powered by GitBook
On this page
  • Introduction
  • Implementing a Service
  • Accessing a Service
  • Service Lifecycle
  1. Developer Guide

Services

An overview of services and how to use them

PreviousPolicy FrameworkNextMessaging Framework

Last updated 7 years ago

Introduction

Services are software entities that operate in the background of the application, and outside of the , , and . Services are singletons as well—meaning only one instance of the service exists at all times.

Examples of services include:

  • Connection manager for MongoDB

  • Local caching algorithm for a content delivery network (CDN)

  • Gateway for communicating with Firebase Cloud Messaging

All services are located in app/services.

Implementing a Service

You implement a service by extending the Service class. Here is an example service for storing the .

app/services/messages.js

const { Service } = require ('@onehilltech/blueprint');

module.exports = Service.extend ({
  _messages: null,
  
  init () {
    this._super.call (this, ...arguments);
    this._messages = [];
  },
  
  push (msg) {
    this._messages.push (msg);
  },
  
  find (id) {
    return this._messages.find (msg => msg.id === id);
  }
});

As shown in the example implementation above, the service has methods for adding and finding messages.

Accessing a Service

You access a service by defining a property with the value service([name]). This method will bind the service to the associated property.

The name parameter is require if the (file) name of the service does not match the name of the property. For example, if a service is in a file named local-cache, then you must use service('local-cache')to access the service.

Below, we have re-implemented the message controller to use the message service.

const {Controller, model, service} = require ('@onehilltech/blueprint');

module.exports = Controller.extend ({
  messages: service (),       // access the messages service
  Message: model ('message'),
  
  create () {
    return Action.extend ({
      _nextId: 0,      // id of the next message
      
      // ...
      
      execute (req, res) {
        let id = this._nextId ++;
        let data = Object.assign ({id}, pick (req.body.message, ['from','to','date','subject','content']));
        let msg = this.Message.create (data);
        
        this.controller.messages.push (msg);
        
        res.status (200).json ({message: msg});
      }
    })
  },
  
  getOne () {
    return Action.extend ({
      // ...
      
      execute (req, res) {
        const {messageId} = req.params;
        const found = this.controllers.messages.find (messageId);
        
        if (found)
          return res.status (200).json ({message: found});
        else
          return res.sendStatus (404);  
      }
    });
  }
});

In the example above, you will notice that the messages property has been changed from an array to a reference to the messages service. Now, the controller will read and write message to and from the messages service. More importantly, other entities can access this service and manipulate to the same messages this controller is able to manipulate.

Service Lifecycle

  1. configure This method is called when the service is to configure itself. The configure() method should not be confused with the init() method. The init() method is for synchronous configuration whereas the configure() method is for asynchronous configuration. This is because the configure method can return a Promise to signify asynchronous configuration.

  2. start This method is called when the service is started. If the service must perform any asynchronous operations, then it can return a Promise.

  3. destroy This method is called when the service is being destroyed. If the service must perform any asynchronous operations, then it can return a Promise.

Services are loaded automatically by the application after the application has loaded its . Once the service is loaded into member, its lifecycle methods are called in the following order:

configuration files
controllers
routers
listeners
messages we originally stored in a controller