synapsestudios/synapse-base

This package is abandoned and no longer maintained. No replacement package was suggested.

Base code for the API template


README

Build Status

Overview

Synapse Base is a bootstrapping library for PHP applications build in the Silex microframework. It's intended for REST APIs that serve and consume JSON.

This library provides an opinionated, secure starting point for your REST API using the following tools and libraries:

Setting up your Project

Quick Start

For new projects, just clone the API Template as a starting point and composer install.

Expectations of the Library

Architectural Expectations

  1. A MySQL server for app data
  2. A Redis server for job queues

Project Codebase Expectations

(If you just use API Template, you don't need to know most of this.)

  1. Some named constants are expected to exist.
  2. The APP_ENV environment variable should be set. (To development, production, or staging.)
  3. Specific config files should be set up in [APPDIR]/config/. To set up environment-specific configuration overrides, put identical config files in [APPDIR]/config/development/, etc. See API Template for examples.

Setting Up Required Config Files

The default config files contain sufficient documentation in DocBlocks. Just read those.

Database Interaction

Database Installs and Migrations

Use the console utility in API Template to perform DB installs and migrations.

  • Install a clean copy of the database: ./console install:run --drop-tables
  • Create a migration: ./console migrations:create "Add inventory table"
  • Install any migrations that haven't been applied: ./console migrations:run (Or just ./console install:run)
  • Generate a new database install file from the current state of the database: ./console install:generate

When you create a new migration, it's created in [APPDIR]/src/Application/Migrations/. Use the Zend DB Adapter to perform queries like this.

Note about Generating a Database Install File: When you run ./console install:generate, it generates 2 files -- (1) a DbStructure.sql file with the table structure based on the current snapshot of your database, and (2) a DbData.sql file with data from specific tables. Specify which tables in the install config.

How to Read/Write from the Database

Use Mappers like this to perform database queries. Database results are returned as Entities.

Authentication / Login System

bshaffer's OAuth2 server is used for authentication. The user POSTs to /oauth/token with their email/password and receives an access token which can be used to make requests. (Per the OAuth2 specification.)

In order to secure endpoints, the Symfony Security module is used. Firewalls are used to constrain an endpoint to logged in users or to make it public. Access Rules are used to make an endpoint accessible only to users with certain roles. Read the Symfony Security docs for more details.

Notes:

  1. When you specify a listener in a firewall ('anonymous' => true, 'oauth-optional' => true), the code that runs is in the Listeners. (These are added in the OAuth2\SecurityServiceProvider.)
  2. There is a catch-all firewall that constrains all endpoints to be protected by OAuth (non-public) unless specified otherwise. More details here.

Utility Classes

Array Helper

$people = [
    ['name' => 'Linus',   'age' => 10],
    ['name' => 'Brendan', 'age' => 11],
    ['name' => 'Rasmus',  'age' => 12, 'colors' => ['Red', 'Green', 'Blue']],
];

Arr::get($people[0], 'name');     // Linus
Arr::get($people[3], 'name');     // null
Arr::pluck($people, 'name');      // ['Linux', 'Brendan', 'Rasmus'];
Arr::path($people, '2.colors.1'); // Green

DataObject

Use these to encapsulate concepts and typehint them in your app.

class Car extends DataObject
{
    protected $object = [
        'make'    => null,
        'model'   => null,
        'year'    => null,
        'totaled' => false,
    ];
}

$car = new Car(['make' => 'Toyota']);
$car->setModel('Corolla');
$car->getMake();    // Toyota
$car->getModel();   // Corolla
$car->getYear();    // null
$car->getTotaled(); // false

// These are helpful for typehinting purposes to make your code more robust
function purchaseCar(Car $car) {
    // Do stuff
}

Test Helpers

Various abstract PHPUnit test cases are available for controllers, mappers, etc., to make it easier to test them.