Step 6. Services and versioning

A facade’s RESTful operations are implemented by REST services, which receive external requests and delegate their execution to operations.

To process requests made to the API’s first version, let’s create a file named FacadeServiceV1.py in the services/version1 folder with the following code:

/src/services/version1/FacadeServiceV1.ts

import { IReferences } from 'pip-services3-commons-nodex';
import { ConfigParams } from 'pip-services3-commons-nodex';
import { RestService } from 'pip-services3-rpc-nodex';
import { AboutOperations } from 'pip-services3-rpc-nodex';

import { AuthorizerV1 } from '../version1/AuthorizerV1';
import { SessionsOperationsV1 } from '../../operations/version1/SessionsOperationsV1';
import { SitesOperationsV1 } from '../../operations/version1/SitesOperationsV1';
import { InvitationsOperationsV1 } from '../../operations/version1/InvitationsOperationsV1';
import { BeaconsOperationsV1 } from '../../operations/version1/BeaconsOperationsV1';

export class FacadeServiceV1 extends RestService {
    private _aboutOperations = new AboutOperations();
    private _sessionsOperations = new SessionsOperationsV1();
    private _sitesOperations = new SitesOperationsV1();
    private _invitationsOperations = new InvitationsOperationsV1();
    private _beaconsOperations = new BeaconsOperationsV1();

    public constructor() {
        super();
        this._baseRoute = "api/v1"
    }

    public configure(config: ConfigParams): void {
        super.configure(config);

        this._aboutOperations.configure(config);
        this._sessionsOperations.configure(config);
        this._sitesOperations.configure(config);
        this._invitationsOperations.configure(config);
        this._beaconsOperations.configure(config);
    }

    public setReferences(references: IReferences): void {
        super.setReferences(references);
        
        this._aboutOperations.setReferences(references);
        this._sessionsOperations.setReferences(references);
        this._sitesOperations.setReferences(references);
        this._invitationsOperations.setReferences(references);
        this._beaconsOperations.setReferences(references);
    }   

    public register(): void {
        let auth = new AuthorizerV1();

        // Restore session middleware
        this.registerInterceptor('',
            (req, res, next) => { this._sessionsOperations.loadSession(req, res, next); });

        // About Route
        this.registerRouteWithAuth('get', '/about', null, auth.anybody(),
            (req, res) => { this._aboutOperations.about(req, res); });

        // Session Routes
        this.registerRouteWithAuth('post', '/signup', null, auth.anybody(),
            (req, res) => { this._sessionsOperations.signup(req, res); });
        this.registerRouteWithAuth('get', '/signup/validate', null, auth.anybody(),
            (req, res) => { this._sessionsOperations.signupValidate(req, res); });
        this.registerRouteWithAuth('post', '/signin', null, auth.anybody(),
            (req, res) => { this._sessionsOperations.signin(req, res); });
        this.registerRouteWithAuth('post', '/signout', null, auth.anybody(),
            (req, res) => { this._sessionsOperations.signout(req, res); });
        this.registerRouteWithAuth('get', '/sessions', null, auth.admin(),
            (req, res) => { this._sessionsOperations.getSessions(req, res); });
        this.registerRouteWithAuth('post', '/sessions/restore', null, auth.signed(),
            (req, res) => { this._sessionsOperations.restoreSession(req, res); });
        this.registerRouteWithAuth('get', '/sessions/current', null, auth.signed(),
            (req, res) => { this._sessionsOperations.getCurrentSession(req, res); });
        this.registerRouteWithAuth('get', '/sessions/:user_id', null, auth.ownerOrAdmin('user_id'),
            (req, res) => { this._sessionsOperations.getUserSessions(req, res); });
        this.registerRouteWithAuth('del', '/sessions/:user_id/:session_id', null, auth.ownerOrAdmin('user_id'),
            (req, res) => { this._sessionsOperations.closeSession(req, res); });

        // Site Routes
        this.registerRouteWithAuth('get', '/sites', null, auth.signed(),
            (req, res) => { this._sitesOperations.getAuthorizedSites(req, res); });
        this.registerRouteWithAuth('get', '/sites/all', null, auth.admin(),
            (req, res) => { this._sitesOperations.getSites(req, res); });
        this.registerRouteWithAuth('get', '/sites/find_by_code', null, auth.anybody(),
            (req, res) => { this._sitesOperations.findSiteByCode(req, res); });
        this.registerRouteWithAuth('get', '/sites/:site_id', null, auth.siteUser(),
            (req, res) => { this._sitesOperations.getSite(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/generate_code', null, auth.siteAdmin(),
            (req, res) => { this._sitesOperations.generateCode(req, res); });
        this.registerRouteWithAuth('post', '/sites', null, auth.signed(),
            (req, res) => { this._sitesOperations.createSite(req, res); });
        this.registerRouteWithAuth('post', '/sites/validate_code', null, auth.signed(),
            (req, res) => { this._sitesOperations.validateSiteCode(req, res); });
        this.registerRouteWithAuth('put', '/sites/:site_id', null, auth.siteAdmin(),
            (req, res) => { this._sitesOperations.updateSite(req, res); });
        this.registerRouteWithAuth('del', '/sites/:site_id', null, auth.admin(),
            (req, res) => { this._sitesOperations.deleteSite(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/remove', null, auth.siteUser(),
            (req, res) => { this._sitesOperations.removeSite(req, res); });

        // Invitation Routes
        this.registerRouteWithAuth('get', '/sites/:site_id/invitations', null, auth.siteUser(),
            (req, res) => { this._invitationsOperations.getInvitations(req, res); });
        this.registerRouteWithAuth('get', '/sites/:site_id/invitations/:invitation_id', null, auth.siteUser(),
            (req, res) => { this._invitationsOperations.getInvitation(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/invitations', null, auth.signed(),
            (req, res) => { this._invitationsOperations.sendInvitation(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/invitations/notify', null, auth.siteManager(),
            (req, res) => { this._invitationsOperations.notifyInvitation(req, res); });
        this.registerRouteWithAuth('del', '/sites/:site_id/invitations/:invitation_id', null, auth.siteManager(),
            (req, res) => { this._invitationsOperations.deleteInvitation(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/invitations/:invitation_id/approve', null, auth.siteManager(),
            (req, res) => { this._invitationsOperations.approveInvitation(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/invitations/:invitation_id/deny', null, auth.siteManager(),
            (req, res) => { this._invitationsOperations.denyInvitation(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/invitations/:invitation_id/resend', null, auth.siteManager(),
            (req, res) => { this._invitationsOperations.resendInvitation(req, res); });

        // Beacon Routes
        this.registerRouteWithAuth('get', '/sites/:site_id/beacons', null, auth.siteUser(),
            (req, res) => { this._beaconsOperations.getBeacons(req, res); });
        this.registerRouteWithAuth('get', '/sites/:site_id/beacons/:beacon_id', null, auth.siteUser(),
            (req, res) => { this._beaconsOperations.getBeacon(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/beacons/calculate_position', null, auth.siteManager(),
            (req, res) => { this._beaconsOperations.calculatePosition(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/beacons', null, auth.siteManager(),
            (req, res) => { this._beaconsOperations.createBeacon(req, res); });
        this.registerRouteWithAuth('post', '/sites/:site_id/beacons/validate_udi', null, auth.signed(),
            (req, res) => { this._beaconsOperations.validateBeaconUdi(req, res); });
        this.registerRouteWithAuth('put', '/sites/:site_id/beacons/:beacon_id', null, auth.siteManager(),
            (req, res) => { this._beaconsOperations.updateBeacon(req, res); });
        this.registerRouteWithAuth('del', '/sites/:site_id/beacons/:beacon_id', null, auth.siteManager(),
            (req, res) => { this._beaconsOperations.deleteBeacon(req, res); });
    }
}

/src/service/services/version1/FacadeServiceV1.cs

using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Rpc.Services;
using Pip.Services.SampleFacade.Operations.Version1;
using System;
using System.Collections.Generic;

namespace Pip.Services.SampleFacade.Services.Version1
{
    public class FacadeServiceV1 : RestService
    {
		private AboutOperations _aboutOperations = new AboutOperations();
		private SessionsOperationsV1 _sessionsOperations = new SessionsOperationsV1();
		private InvitationsOperationsV1 _invitationsOperations = new InvitationsOperationsV1();
		private SitesOperationsV1 _sitesOperations = new SitesOperationsV1();
		private BeaconsOperationsV1 _beaconsOperations = new BeaconsOperationsV1();

		public FacadeServiceV1()
		{
			_baseRoute = "api/v1";
		}

		public override void Configure(ConfigParams config)
		{
			base.Configure(config);

			_aboutOperations.Configure(config);
			_sessionsOperations.Configure(config);
			_invitationsOperations.Configure(config);
			_sitesOperations.Configure(config);
			_beaconsOperations.Configure(config);
		}

		public override void SetReferences(IReferences references)
		{
			base.SetReferences(references);

			_aboutOperations.SetReferences(references);
			_sessionsOperations.SetReferences(references);
			_invitationsOperations.SetReferences(references);
			_sitesOperations.SetReferences(references);
			_beaconsOperations.SetReferences(references);
		}

		public override void Register()
        {
			var auth = new AuthorizerV1();

			// Restore session middleware
			RegisterInterceptor("",
				async (request, response, user, routeData, next) => { await _sessionsOperations.LoadSessionAsync(request, response, user, routeData, next); });

			// About Route
			RegisterRouteWithAuth("get", "/about", auth.Anybody(),
				async (request, response, user, routeData) => { await _aboutOperations.AboutAsync(request, response, user); });

			// Beacon Routes
			RegisterBeacons(auth);

			// Session Routes
			RegisterSession(auth);

			// Site Routes
			RegisterSite(auth);

			// Invitation Routes
			RegisterInvitation(auth);
		}

		private void RegisterInvitation(AuthorizerV1 auth)
		{
			RegisterRouteWithAuth("get", "/sites/{site_id}/invitations", auth.SiteUser(),
				async (request, response, user, routeData) => { await _invitationsOperations.GetInvitationsAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("get", "/sites/{site_id}/invitations/{invitation_id}", auth.SiteUser(),
				async (request, response, user, routeData) => { await _invitationsOperations.GetInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/invitations", auth.Signed(),
				async (request, response, user, routeData) => { await _invitationsOperations.SendInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/invitations/notify", auth.SiteManager(),
				async (request, response, user, routeData) => { await _invitationsOperations.NotifyInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("delete", "/sites/{site_id}/invitations/{invitation_id}", auth.SiteManager(),
				async (request, response, user, routeData) => { await _invitationsOperations.DeleteInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/invitations/{invitation_id}/approve", auth.SiteManager(),
				async (request, response, user, routeData) => { await _invitationsOperations.ApproveInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/invitations/{invitation_id}/deny", auth.SiteManager(),
				async (request, response, user, routeData) => { await _invitationsOperations.DenyInvitationAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/invitations/{invitation_id}/resend", auth.SiteManager(),
				async (request, response, user, routeData) => { await _invitationsOperations.ResendInvitationAsync(request, response, user, routeData); });
		}

		private void RegisterSite(AuthorizerV1 auth)
		{
			// Site Routes
			RegisterRouteWithAuth("get", "/sites", auth.Signed(),
				async (request, response, user, routeData) => { await _sitesOperations.GetAuthorizedSitesAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("get", "/sites/all", auth.Admin(),
				async (request, response, user, routeData) => { await _sitesOperations.GetSitesAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("get", "/sites/find_by_code", auth.Anybody(),
				async (request, response, user, routeData) => { await _sitesOperations.FindSiteByCodeAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("get", "/sites/{site_id}", auth.SiteUser(),
				async (request, response, user, routeData) => { await _sitesOperations.GetSiteAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/generate_code", auth.SiteAdmin(),
				async (request, response, user, routeData) => { await _sitesOperations.GenerateCodeAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites", auth.Signed(),
				async (request, response, user, routeData) => { await _sitesOperations.CreateSiteAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/validate_code", auth.Signed(),
				async (request, response, user, routeData) => { await _sitesOperations.ValidateSiteCodeAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("put", "/sites/{site_id}", auth.SiteAdmin(),
				async (request, response, user, routeData) => { await _sitesOperations.UpdateSiteAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("delete", "/sites/{site_id}", auth.Admin(),
				async (request, response, user, routeData) => { await _sitesOperations.DeleteSiteAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/remove", auth.SiteUser(),
				async (request, response, user, routeData) => { await _sitesOperations.RemoveSiteAsync(request, response, user, routeData); });
		}

		private void RegisterSession(AuthorizerV1 auth)
		{
			RegisterRouteWithAuth("post", "/signup", auth.Anybody(),
				async (request, response, user, routeData) => { await _sessionsOperations.SignupAsync(request, response); });
			
			RegisterRouteWithAuth("get", "/signup/validate", auth.Anybody(),
				async (request, response, user, routeData) => { await _sessionsOperations.SignupValidateAsync(request, response); });
			
			RegisterRouteWithAuth("post", "/signin", auth.Anybody(),
				async (request, response, user, routeData) => { await _sessionsOperations.SigninAsync(request, response); });
			
			RegisterRouteWithAuth("post", "/signout", auth.Anybody(),
				async (request, response, user, routeData) => { await _sessionsOperations.SignoutAsync(request, response); });
			
			RegisterRouteWithAuth("get", "/sessions", auth.Admin(),
				async (request, response, user, routeData) => { await _sessionsOperations.GetSessionsAsync(request, response); });
			
			RegisterRouteWithAuth("post", "/sessions/restore", auth.Signed(),
				async (request, response, user, routeData) => { await _sessionsOperations.RestoreSessionAsync(request, response); });
			
			RegisterRouteWithAuth("get", "/sessions/current", auth.Signed(),
				async (request, response, user, routeData) => { await _sessionsOperations.GetCurrentSessionAsync(request, response); });
			
			RegisterRouteWithAuth("get", "/sessions/{user_id}", auth.OwnerOrAdmin("user_id"),
				async (request, response, user, routeData) => { await _sessionsOperations.GetUserSessionsAsync(request, response); });
			
			RegisterRouteWithAuth("delete", "/sessions/{user_id}/{session_id}", auth.OwnerOrAdmin("user_id"),
				async (request, response, user, routeData) => { await _sessionsOperations.CloseSessionAsync(request, response); });
		}

		private void RegisterBeacons(AuthorizerV1 auth)
		{
			RegisterRouteWithAuth("get", "/sites/{site_id}/beacons", auth.SiteUser(),
				async (request, response, user, routeData) => {	await _beaconsOperations.GetBeaconsAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("get", "/sites/{site_id}/beacons/{beacon_id}", auth.SiteUser(),
				async (request, response, user, routeData) => {	await _beaconsOperations.GetBeaconAsync(request, response, user, routeData); });
			
			RegisterRouteWithAuth("post", "/sites/{site_id}/beacons/calculate_position", auth.SiteManager(),
				async (request, response, user, routeData) => {	await _beaconsOperations.CalculatePositionAsync(request, response, user, routeData); });

			RegisterRouteWithAuth("post", "/sites/{site_id}/beacons", auth.SiteManager(),
				async (request, response, user, routeData) => {	await _beaconsOperations.CreateBeaconAsync(request, response, user, routeData);	});

			RegisterRouteWithAuth("post", "/sites/{site_id}/beacons/validate_udi", auth.Signed(),
				async (request, response, user, routeData) => {	await _beaconsOperations.ValidateBeaconUdiAsync(request, response, user, routeData); });

			RegisterRouteWithAuth("put", "/sites/{site_id}/beacons/{beacon_id}", auth.SiteManager(),
				async (request, response, user, routeData) => {	await _beaconsOperations.UpdateBeaconAsync(request, response, user, routeData);	});

			RegisterRouteWithAuth("delete", "/sites/{site_id}/beacons/{beacon_id}", auth.SiteManager(),
				async (request, response, user, routeData) => {	await _beaconsOperations.DeleteBeaconAsync(request, response, user, routeData);	});
		}
    }
}

/services/version1/FacadeServiceV1.go

package services1

import (
	"net/http"

	operations1 "github.com/pip-services-samples/pip-samples-facade-go/operations/version1"
	cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
	cref "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
	rpcservices "github.com/pip-services3-gox/pip-services3-rpc-gox/services"
)

type FacadeServiceV1 struct {
	*rpcservices.RestService
	sessionsOperations *operations1.SessionsOperationsV1
	beaconsOperations  *operations1.BeaconsOperationsV1
}

func NewFacadeServiceV1() *FacadeServiceV1 {
	c := &FacadeServiceV1{
		sessionsOperations: operations1.NewSessionsOperationsV1(),
		beaconsOperations:  operations1.NewBeaconsOperationsV1(),
	}
	c.RestService = rpcservices.InheritRestService(c)
	c.BaseRoute = "api/v1"
	return c
}

func (c *FacadeServiceV1) Configure(config *cconf.ConfigParams) {
	c.RestService.Configure(config)

	c.sessionsOperations.Configure(config)
	c.beaconsOperations.Configure(config)
}

func (c *FacadeServiceV1) SetReferences(references cref.IReferences) {
	c.RestService.SetReferences(references)

	c.sessionsOperations.SetReferences(references)
	c.beaconsOperations.SetReferences(references)
}

func (c *FacadeServiceV1) Register() {
	auth := NewAuthorizerV1()

	// Restore session middleware
	c.RegisterInterceptor("",
		func(res http.ResponseWriter, req *http.Request, next http.HandlerFunc) {
			c.sessionsOperations.LoadSession(res, req, next)
		})

	c.registerContentManagementRoutes(auth)
	c.registerUsersRoutes(auth)
}

func (c *FacadeServiceV1) registerContentManagementRoutes(auth *AuthorizerV1) {
	// Beacons routes
	c.RegisterRouteWithAuth("get", "/beacons", nil, auth.Signed(),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.GetBeacons(res, req) })
	c.RegisterRouteWithAuth("get", "/beacons/{id}", nil, auth.Owner("user_id"),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.GetBeaconById(res, req) })
	c.RegisterRouteWithAuth("get", "/beacons/udi/{udi}", nil, auth.Owner(""),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.GetBeaconByUdi(res, req) })
	c.RegisterRouteWithAuth("post", "/beacons", nil, auth.Signed(),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.CreateBeacon(res, req) })
	c.RegisterRouteWithAuth("put", "/beacons", nil, auth.Signed(),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.UpdateBeacon(res, req) })
	c.RegisterRouteWithAuth("delete", "/beacons/{id}", nil, auth.Signed(),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.DeleteBeaconById(res, req) })
	c.RegisterRouteWithAuth("post", "/beacons/position", nil, auth.Signed(),
		func(res http.ResponseWriter, req *http.Request) { c.beaconsOperations.CalculatePosition(res, req) })
}

func (c *FacadeServiceV1) registerUsersRoutes(auth *AuthorizerV1) {
	// Session Routes
	c.RegisterRouteWithAuth("post", "/users/signup", nil, auth.Anybody(),
		func(res http.ResponseWriter, req *http.Request) { c.sessionsOperations.Signup(res, req) })
	c.RegisterRouteWithAuth("post", "/users/signin", nil, auth.Anybody(),
		func(res http.ResponseWriter, req *http.Request) { c.sessionsOperations.Signin(res, req) })
	c.RegisterRouteWithAuth("post", "/users/signout", nil, auth.Anybody(),
		func(res http.ResponseWriter, req *http.Request) { c.sessionsOperations.Signout(res, req) })
}

Not available

/pip_facades_sample_python/services/version1/FacadeServiceV1.py

# -*- coding: utf-8 -*-
from pip_services3_commons.config import ConfigParams
from pip_services3_commons.refer import IReferences
from pip_services3_rpc.services.AboutOperations import AboutOperations
from pip_services3_rpc.services.RestService import RestService

from pip_facades_sample_python.operations.version1.BeaconsOperationsV1 import BeaconsOperationsV1
from pip_facades_sample_python.operations.version1.InvitationsOperationsV1 import InvitationsOperationsV1
from pip_facades_sample_python.operations.version1.SessionsOperationsV1 import SessionsOperationsV1
from pip_facades_sample_python.operations.version1.SitesOperationsV1 import SitesOperationsV1
from pip_facades_sample_python.services.version1.AuthorizerV1 import AuthorizerV1


class FacadeServiceV1(RestService):

    def __init__(self):
        super(FacadeServiceV1, self).__init__()
        self._base_route = 'api/v1'

        self.__about_operations = AboutOperations()
        self.__session_operations = SessionsOperationsV1()
        self.__sites_operations = SitesOperationsV1()
        self.__invitations_operations = InvitationsOperationsV1()
        self.__beacons_operations = BeaconsOperationsV1()

    def configure(self, config: ConfigParams):
        super().configure(config)

        self.__about_operations.configure(config)
        self.__session_operations.configure(config)
        self.__sites_operations.configure(config)
        self.__invitations_operations.configure(config)
        self.__beacons_operations.configure(config)

    def set_references(self, references: IReferences):
        super().set_references(references)

        self.__about_operations.set_references(references)
        self.__session_operations.set_references(references)
        self.__sites_operations.set_references(references)
        self.__invitations_operations.set_references(references)
        self.__beacons_operations.set_references(references)

    def register(self):
        auth = AuthorizerV1()

        # Restore session middleware
        self.register_interceptor('', lambda: self.__session_operations.load_session())

        self.register_route_with_auth('get', '/about', None, auth.anybody(),
                                      lambda: self.__about_operations.get_about())
        # Session Routes
        self.register_route_with_auth('post', '/signup', None, auth.anybody(),
                                      lambda: self.__session_operations.signup())
        self.register_route_with_auth('get', '/signup/validate', None, auth.anybody(),
                                      lambda: self.__session_operations.signup_validate())
        self.register_route_with_auth('post', '/signin', None, auth.anybody(),
                                      lambda: self.__session_operations.signin())
        self.register_route_with_auth('post', '/signout', None, auth.anybody(),
                                      lambda: self.__session_operations.signout())
        self.register_route_with_auth('get', '/sessions', None, auth.admin(),
                                      lambda: self.__session_operations.get_sessions())
        self.register_route_with_auth('post', '/sessions/restore', None, auth.signed(),
                                      lambda: self.__session_operations.restore_session())
        self.register_route_with_auth('get', '/sessions/current', None, auth.signed(),
                                      lambda: self.__session_operations.get_current_session())
        self.register_route_with_auth('get', '/sessions/:user_id', None, auth.owner_or_admin('user_id'),
                                      lambda user_id: self.__session_operations.get_user_sessions(user_id))
        self.register_route_with_auth('del', '/sessions/:user_id/:session_id', None, auth.owner_or_admin('user_id'),
                                      lambda user_id, session_id: self.__session_operations.close_session(user_id,
                                                                                                          session_id))

        # Site Routes
        self.register_route_with_auth('get', '/sites', None, auth.signed(),
                                      lambda: self.__sites_operations.get_authorized_sites())
        self.register_route_with_auth('get', '/sites/all', None, auth.admin(),
                                      lambda: self.__sites_operations.get_sites())
        self.register_route_with_auth('get', '/sites/find_by_code', None, auth.anybody(),
                                      lambda: self.__sites_operations.find_site_by_code())
        self.register_route_with_auth('get', '/sites/:site_id', None, auth.site_user(),
                                      lambda site_id: self.__sites_operations.get_site(site_id))
        self.register_route_with_auth('post', '/sites/:site_id/generate_code', None, auth.site_admin(),
                                      lambda site_id: self.__sites_operations.generate_code(site_id))
        self.register_route_with_auth('post', '/sites', None, auth.signed(),
                                      lambda: self.__sites_operations.create_site())
        self.register_route_with_auth('post', '/sites/validate_code', None, auth.signed(),
                                      lambda: self.__sites_operations.validate_site_code())
        self.register_route_with_auth('put', '/sites/:site_id', None, auth.site_admin(),
                                      lambda site_id: self.__sites_operations.update_site(site_id))
        self.register_route_with_auth('delete', '/sites/:site_id', None, auth.admin(),
                                      lambda site_id: self.__sites_operations.delete_site(site_id))
        self.register_route_with_auth('post', '/sites/:site_id/remove', None, auth.site_user(),
                                      lambda site_id: self.__sites_operations.remove_site(site_id))

        # Invitation Routes
        self.register_route_with_auth('get', '/sites/:site_id/invitations', None, auth.site_user(),
                                      lambda site_id: self.__invitations_operations.get_invitations(site_id))
        self.register_route_with_auth('get', '/sites/:site_id/invitations/:invitation_id', None, auth.site_user(),
                                      lambda site_id, invitation_id: self.__invitations_operations.get_invitation(
                                          site_id, invitation_id))
        self.register_route_with_auth('post', '/sites/:site_id/invitations', None, auth.signed(),
                                      lambda site_id: self.__invitations_operations.send_invitation(site_id))
        self.register_route_with_auth('post', '/sites/:site_id/invitations/notify', None, auth.site_manager(),
                                      lambda site_id: self.__invitations_operations.notify_invitation(site_id))
        self.register_route_with_auth('delete', '/sites/:site_id/invitations/:invitation_id', None, auth.site_manager(),
                                      lambda site_id, invitation_id: self.__invitations_operations.delete_invitation(
                                          site_id, invitation_id))
        self.register_route_with_auth('post', '/sites/:site_id/invitations/:invitation_id/approve', None,
                                      auth.site_manager(),
                                      lambda site_id, invitation_id: self.__invitations_operations.approve_invitation(
                                          site_id, invitation_id))
        self.register_route_with_auth('post', '/sites/:site_id/invitations/:invitation_id/deny', None,
                                      auth.site_manager(),
                                      lambda site_id, invitation_id: self.__invitations_operations.deny_invitation(
                                          site_id, invitation_id))
        self.register_route_with_auth('post', '/sites/:site_id/invitations/:invitation_id/resend', None,
                                      auth.site_manager(),
                                      lambda site_id, invitation_id: self.__invitations_operations.resend_invitation(
                                          site_id, invitation_id))

        # Beacon Routes
        self.register_route_with_auth('get', '/sites/:site_id/beacons', None, auth.site_user(),
                                      lambda site_id: self.__beacons_operations.get_beacons(site_id))
        self.register_route_with_auth('get', '/sites/:site_id/beacons/:beacon_id', None, auth.site_user(),
                                      lambda site_id, beacon_id: self.__beacons_operations.get_beacon(site_id,
                                                                                                      beacon_id))
        self.register_route_with_auth('post', '/sites/:site_id/beacons/calculate_position', None, auth.site_user(),
                                      lambda site_id: self.__beacons_operations.calculate_position(site_id))
        self.register_route_with_auth('post', '/sites/:site_id/beacons', None, auth.site_user(),
                                      lambda site_id: self.__beacons_operations.create_beacon(site_id))
        self.register_route_with_auth('post', '/sites/:site_id/beacons/validate_udi', None, auth.signed(),
                                      lambda site_id: self.__beacons_operations.validate_beacon_udi(site_id))
        self.register_route_with_auth('put', '/sites/:site_id/beacons/:beacon_id', None, auth.site_user(),
                                      lambda site_id, beacon_id: self.__beacons_operations.update_beacon(site_id,
                                                                                                         beacon_id))
        self.register_route_with_auth('delete', '/sites/:site_id/beacons/:beacon_id', None, auth.site_user(),
                                      lambda site_id, beacon_id: self.__beacons_operations.delete_beacon(site_id,
                                                                                                         beacon_id))
Not available

The FacadeServiceV1 component extends the standard RestService, which implements the majority of the component’s basic functionality. All that we have left to do is define some routes and delegate their processing to the operations we defined in the previous steps.

A base route is defined in the constructor, which contains the API version that is implemented in the service.

In the register method, before we register our routes, we make sure to register the load_session interceptor, which will be loading user sessions using the parameters set in the REST requests.

Next, the routes are registered, access limits are set up using our Authorizer, and request handlers are defined using the business methods we implemented in our REST operation sets. For the sake of convenience, the registration functions are divided into 2 groups, each of which belongs to a specific operation-component.

When implementing a new version of the API, the following must be done:

  1. Implement new REST operations or modify a copy of the existing ones;
  2. Create a new FacadeServiceVx and set a new “/api/vx” base route;
  3. Register routes for the new API and delegate their processing to the newly added and to already existing REST operations.

Continue on to Step 7 - Testing of Operations to see how we can automate the testing of the service and operations we’ve created, including the authentication and authorization of requests.

Step 7 - Testing of Operations