API Overview
The Syneo/Barcoding API is built on LoopBack 4, a highly extensible Node.js and TypeScript framework for building APIs.
Architecture
The API follows a layered architecture:
┌─────────────────────────────────────────┐
│ HTTP Layer (REST) │
│ - Controllers (606+) │
│ - Request validation │
│ - Response formatting │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Business Logic Layer │
│ - Services (22) │
│ - Business rules │
│ - External integrations │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Data Access Layer │
│ - Repositories (582+) │
│ - Model definitions │
│ - Relations │
└──────────────┬──────────────────────────┘
│
┌──────────────▼──────────────────────────┐
│ Database Layer │
│ - MySQL connector │
│ - Connection pooling │
│ - Transaction management │
└─────────────────────────────────────────┘Key Features
OpenAPI Specification
The API automatically generates OpenAPI (Swagger) documentation:
Explorer URL: http://localhost:3001/explorer
The OpenAPI spec is used to:
- Generate interactive API documentation
- Auto-generate the
@barcoding/sdkclient - Validate requests and responses
- Define API contracts
Dependency Injection
LoopBack 4 provides built-in dependency injection:
typescript
export class TicketController {
constructor(
@repository(TicketRepository)
public ticketRepository: TicketRepository,
@inject('services.NotificationService')
protected notificationService: NotificationService,
) {}
}JWT Authentication
The API uses JWT (JSON Web Tokens) for authentication:
typescript
@authenticate('jwt')
@get('/tickets')
async findTickets(): Promise<Ticket[]> {
return this.ticketRepository.find();
}Database Migrations
Schema changes are managed with Knex migrations:
bash
# Create migration
npx knex migrate:make add_status_to_tickets
# Run migrations
npm run migrateProject Structure
api/b3api/
├── src/
│ ├── controllers/ # 606+ REST endpoints
│ │ ├── ticket.controller.ts
│ │ ├── user.controller.ts
│ │ └── ...
│ ├── repositories/ # 582+ data repositories
│ │ ├── ticket.repository.ts
│ │ ├── user.repository.ts
│ │ └── ...
│ ├── services/ # 22 business services
│ │ ├── notification.service.ts
│ │ ├── email.service.ts
│ │ └── ...
│ ├── models/ # Data models
│ │ ├── ticket.model.ts
│ │ ├── user.model.ts
│ │ └── ...
│ ├── datasources/ # Database connections
│ │ └── mysqldb01.datasource.ts
│ ├── knex_migrations/ # Database migrations
│ │ ├── 20240101000000_initial.ts
│ │ └── ...
│ ├── application.ts # LoopBack application
│ ├── index.ts # Entry point
│ └── sequence.ts # Request sequence
├── dist/ # Compiled output
├── package.json
└── tsconfig.jsonAPI Statistics
- Controllers: 606+
- Repositories: 582+
- Services: 22
- Models: 500+
- Datasources: 1 (MySQL)
Development Workflow
1. Start the API
bash
cd api/b3api
npm run build
npm run startAPI will be available at:
- API Base:
http://localhost:3001 - Explorer:
http://localhost:3001/explorer - OpenAPI Spec:
http://localhost:3001/openapi.json
2. Make Changes
Edit files in src/:
typescript
// src/controllers/ticket.controller.ts
@post('/tickets')
async createTicket(@requestBody() ticket: Ticket): Promise<Ticket> {
return this.ticketRepository.create(ticket);
}3. Rebuild
bash
npm run build
# Or watch mode
npm run build:watch4. Test
bash
# Run tests
npm run test
# Lint
npm run lint5. Update SDK
After API changes:
bash
cd web
yarn build-sdkConfiguration
Database Connection
Configuration in src/datasources/mysqldb01.datasource.config.json:
json
{
"name": "mysqldb01",
"connector": "mysql",
"host": "mysqldb",
"port": 3306,
"user": "root",
"password": "Ypp01o#3",
"database": "lb4",
"multipleStatements": true
}WARNING
Development credentials only. Never use in production.
Application Configuration
The API loads configuration from:
- Environment variables
- Azure KeyVault (production)
- Default configuration files
Common Tasks
Create a New Controller
bash
lb4 controller
? Controller class name: Product
? What kind of controller would you like to generate? REST Controller with CRUD functions
? What is the name of the model to use with this CRUD repository? Product
? What is the name of your CRUD repository? ProductRepository
? What is the type of your ID? number
? What is the base HTTP path name of the CRUD operations? /productsCreate a New Model
bash
lb4 model
? Model class name: Product
? Please select the model base class: Entity
? Allow additional properties? NoCreate a New Repository
bash
lb4 repository
? Please select the datasource: Mysqldb01Datasource
? Select the model(s) you want to generate a repository for: ProductCreate a New Service
bash
lb4 service
? Service type: proxy
? Please enter the name of the service: EmailService
? Please enter the name of the datasource: EmailDatasourceTesting
Unit Tests
bash
npm run testManual Testing with Explorer
- Open
http://localhost:3001/explorer - Select an endpoint
- Click "Try it out"
- Fill in parameters
- Execute
Automated API Tests
Tests use Mocha and the ApiTestHelper:
typescript
describe('TicketController', () => {
let app: B3ApiApplication;
let client: Client;
before(async () => {
app = await setupApplication();
client = createRestAppClient(app);
});
after(async () => {
await app.stop();
});
it('should create a ticket', async () => {
const ticket = { title: 'Test', status: 'open' };
const response = await client
.post('/tickets')
.send(ticket)
.expect(200);
expect(response.body).to.have.property('id');
});
});Next Steps
- Getting Started with API - Set up development environment
- Database Migrations - Learn about schema management
- Controllers - Deep dive into controllers
- Authentication - Learn about JWT auth