{"id":13990852,"url":"https://github.com/alterior-mvc/alterior","last_synced_at":"2025-04-30T23:19:56.909Z","repository":{"id":11215127,"uuid":"68751334","full_name":"alterior-mvc/alterior","owner":"alterior-mvc","description":"Build HTTP services with this; a Typescript REST framework based on Express using decorators and Angular style dependency injection","archived":false,"fork":false,"pushed_at":"2025-02-09T02:00:23.000Z","size":12352,"stargazers_count":16,"open_issues_count":10,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-20T04:09:02.550Z","etag":null,"topics":["dependency-injection","framework","javascript","typescript","webservices"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alterior-mvc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-20T20:37:52.000Z","updated_at":"2025-04-09T10:11:19.000Z","dependencies_parsed_at":"2024-02-09T10:24:12.624Z","dependency_job_id":"870e5469-d934-4642-9528-2a7cf0074fc8","html_url":"https://github.com/alterior-mvc/alterior","commit_stats":{"total_commits":981,"total_committers":3,"mean_commits":327.0,"dds":"0.012232415902140636","last_synced_commit":"065bbf8bc773c16192e9ba435866c31bb3fdb37e"},"previous_names":[],"tags_count":192,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alterior-mvc%2Falterior","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alterior-mvc%2Falterior/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alterior-mvc%2Falterior/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alterior-mvc%2Falterior/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alterior-mvc","download_url":"https://codeload.github.com/alterior-mvc/alterior/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251795899,"owners_count":21645100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","framework","javascript","typescript","webservices"],"created_at":"2024-08-09T13:03:24.226Z","updated_at":"2025-04-30T23:19:56.890Z","avatar_url":"https://github.com/alterior-mvc.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Framework Interoperability"],"sub_categories":["External Integration"],"readme":"# ![Alterior](./logo.svg) [![CircleCI](https://circleci.com/gh/alterior-mvc/alterior/tree/main.svg?style=shield)](https://circleci.com/gh/alterior-mvc/alterior/tree/main) [![Join the chat at https://gitter.im/alterior-mvc/Lobby](https://badges.gitter.im/alterior-core/Lobby.svg)](https://gitter.im/alterior-mvc/Lobby?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) ![License](https://img.shields.io/npm/l/@alterior/runtime.svg) [![npm](https://img.shields.io/npm/v/@alterior/runtime)](https://alterior-mvc.github.io/alterior/index.html?)\n\n[NPM](https://www.npmjs.com/org/alterior) | [Github](https://github.com/alterior-mvc/alterior) | [API reference](https://alterior-mvc.github.io/alterior/index.html?) | [Changelog](CHANGELOG.md)\n\nA framework for building well-structured applications and isomorphic libraries in Typescript.\n\n# Overview\n\nAlterior is an isomorphic framework for building service-oriented applications composed of executable modules which participate in dependency injection and declare \ncomponents. \n\nAlterior's Modules are well-defined units of execution which have a defined lifecycle, \nand respond to standardized lifecycle events. This makes them suitable for use as a \nprimary vehicle for top-level general purpose code, such as a server or even a desktop \napplication. \n\n## Class Libraries\n\nAlterior strives to provide a strong isomorphic base class library that fills \nthe gaps between ECMAScript and larger BCLs like Java or .NET. In service of \nthis, Alterior ships low-level libraries for handling decorators/annotations, \nerrors and error base classes, dependency injection, an HTTP client, and more. \n\n# Getting Started\n\nAlterior is **not just a REST framework**, but that's certainly it's most common usage.\n\n```typescript\nimport '@alterior/platform-nodejs';\nimport { WebService, Get, WebServerEngine } from '@alterior/web-server';\nimport { Application } from '@alterior/runtime';\nimport { ExpressEngine } from '@alterior/express';\n\nWebServerEngine.default = ExpressEngine;\n\n@WebService()\nexport class MyWebService {\n    @Get('/service-info')\n    info() {\n      return { \n        service: 'my-web-service' \n      };\n    }\n}\n\nApplication.bootstrap(MyWebService);\n```\n\nFor more information on building web services with Alterior, see [@alterior/web-server](packages/web-server/README.md).\n\n## Consuming your web service\n\nA web service built with Alterior can be consumed on the client transparently. This is an example of a [Transparent Service](https://github.com/alterior-mvc/alterior/wiki/TransparentServicesPlanning)\n\n```typescript\nimport { MyWebService } from '@example/my-backend';\nimport { Component } from '@angular/core';\n\n@Component({ selector: 'my-component', ... })\nexport class MyComponent {\n  constructor(\n    private service : MyWebService\n  ) {\n  }\n\n  onButtonClicked() {\n    let serviceInfo = await this.service.info();\n    console.log(serviceInfo);\n    // { service: 'my-web-service' }\n  }\n}\n```\n\nTransparent services are not limited to being used in Angular. The simplest way to consume a service on the frontend is to create it using Service.bootstrap()\n\n```typescript\nimport { Service } from '@alterior/runtime';\nimport { MyWebService } from '@example/my-backend';\n\nlet service = Service.bootstrap(MyWebService);\n```\n\n## Creating a project\n\nStart by installing the Alterior command line tooling:\n\n```\nnpm install @alterior/cli -g\n```\n\nThen you can generate a new Alterior service:\n\n```\nalt new service my-web-service\n```\n\nA new folder called `my-web-service` will be created containing a fully formed Alterior project. To start the service, enter the new folder and call\n\n```\nnpm start\n```\n\nTo publish the project to NPM for use in your frontend, use\n\n```\nnpm publish\n```\n\nAlterior automatically handles everything needed to build and publish your application, including removing your actual backend code if you have asked for that.\n\n## Do I have to use the CLI?\n\nYou can build an Alterior project using `tsc` (or any other Typescript compiler) if you wish, but not all of Alterior's features will be available. Transparent Services in particular are enabled via the Alterior CLI build process, so much of the benefits of that feature would be unavailable without additional work.\n\nAdditionally, Alterior's builtin build process emits runtime type reflection information for all elements, even when there are no decorators present. Typescript itself only emits type metadata for decorated elements, so you may have to add decorators where there are none are needed when Alterior is built by its own CLI. \n\nIf you choose not to use Alterior CLI's build step, you may want to use the [ttypescript](https://github.com/cevek/ttypescript) frontend instead of `tsc` and add a transform for emitting all type metadata. The one that Alterior uses is currently built-in to `@alterior/cli`, but we plan to roll it out as a standalone transformer in the near future.\n\n# Mechanics\n\nAlterior is not just for building REST services. Here's a minimal single file example of an application that is something other than a `@WebService`.\n\n```typescript\nimport 'reflect-metadata';\nimport { Module, OnInit, AppOptions, Application } from '@alterior/runtime';\n\n@Module()\nexport class AppModule implements OnInit {\n    public altOnInit() {\n        console.log('Hello world!');\n    }\n}\n\nApplication.bootstrap(AppModule);\n```\n\nThis becomes useful because Alterior modules can participate in dependency injection and builtin lifecycle management functionality. A class decorated with `@WebService()` is also considered an `@Module()`.\n\n### Dependency Injection\n\nBootstrapped classes can participate in dependency injection. \n\n```typescript\nimport 'reflect-metadata';\nimport { Module, OnInit, AppOptions, Application } from '@alterior/runtime';\nimport { Injectable } from '@alterior/di';\n\n@Injectable()\nexport class WorldService {\n  theWorld() {\n    return 'world';\n  }\n}\n\n@Injectable()\nexport class HelloService {\n  constructor(\n    private world : WorldService\n  ) {\n  }\n\n  sayHello() {\n    return `hello, ${this.world.theWorld()}`;\n  }\n}\n\n@Module()\nexport class AppModule implements OnInit {\n    constructor(\n      private hello : HelloService\n    ) {\n    }\n\n    public altOnInit() {\n        console.log(this.hello.sayHello());\n    }\n}\n\nApplication.bootstrap(AppModule);\n```\n\n### Lifecycle Management\n\nModules can have any of the following lifecycle methods which act as hooks for running custom behaviors\n\n- **`altOnInit()`** Called when the module is bootstrapped. Implement the `OnInit` interface when using this lifecycle method. \n- **`altOnStart()`** Called when the overall application is started. Implement the `OnStart` interface when using this lifecycle method.\n- **`altOnStop()`** Called when the overall application is stopped before exiting. Implement the `OnStop` interface when using this lifecycle method.\n- **`RolesService`** The notion of \"roles\" is used to allow a module to define or react to a certain class of functionality being started or stopped. For instance `@/web-server` adds a `web-server` role which can be enabled or disabled at configuration time to control whether the web server portion of the application is enabled or disabled. Similarly `@/tasks` adds a `task-worker` role. By default all roles \nare started when the application starts. This can be used to start only a specific portion of an application in a particular environment, for instance having the web server and task worker roles started in development, but splitting these into separate tiers in production.\n\nFor more information about lifecycle management, see [the Roles section of the @/runtime documentation](packages/runtime/README.md#roles).\n\n# Packages\nAlterior consists of the following individual NPM packages. You can pull in \npackages as you need them.\n\n- **[@alterior/annotations](packages/annotations/README.md)** A system for decorating and introspecting standardized metadata on programmatic elements in Typescript  \n  \n- **[@alterior/common](packages/common/README.md)** Provides many smaller quality-of-life utilities which can save you\ntime while you build your applications.  \n\n- **[@alterior/command-line](packages/command-line/README.md)** Command line arguments handling  \n\n- **[@alterior/cli](packages/cli/README.md)** The Alterior CLI tool  \n\n- **[@alterior/di](packages/di/README.md)** Provides a flexible Angular-style dependency injection framework based on `injection-js`  \n\n- **[@alterior/http](packages/http/README.md)** HTTP client library as an Alterior module (ported from `@angular/http`)  \n  \n- **[@alterior/logging](packages/logging/README.md)** A logging library which supports pluggable listeners and context-tracked logging using `Zone.js`  \n\n- **[@alterior/platform-angular](packages/platform-angular/README.md)** Provides support for loading Alterior modules into an Angular app, including the ability to access Alterior injectable services from Angular components and services. Use this to consume isomorphic libraries from within frontend apps written in Angular.\n\n- **[@alterior/platform-nodejs](packages/platform-nodejs/README.md)** Provides support for bootstrapping an Alterior application within the Node.js server environment.  \n\n- **[@alterior/rtti](packages/rtti/README.md)** A Typescript transformer for emitting comprehensive runtime type information (RTTI)\n\n- **[@alterior/runtime](packages/runtime/README.md)** An module-based dependency injection and lifecycle event system similar to that of Angular, suitable for use in Alterior libraries and applications.  \n\n- **[@alterior/tasks](packages/tasks/README.md)** A system for enqueuing and processing tasks using Redis as it's backing store (based on `bull` queue)\n\n- **[@alterior/web-server](packages/web-server/README.md)** A system for building RESTful web services declaratively using classes \u0026 decorators\n\n## Compatibility\n\n### Using Alterior modules in Angular\n\nYou can use any browser-compatible Alterior module in Angular by using  \n`@alterior/platform-angular`:\n\n```typescript\nimport { AngularPlatform } from '@alterior/angular-platform';\nimport { MyAlteriorModule, MyAlteriorService } from '@my/alterior-module';\n\n@NgModule({\n  providers: [\n    AngularPlatform.bridge(\n      MyAlteriorModule,\n      // ...\n    )\n  ]\n})\nexport class AppModule {\n  constructor(\n    someAlteriorService : MyAlteriorService\n  ) {\n    console.log(`The following service was injected from an Alterior module:`);\n    console.log(someAlteriorService);\n  }\n}\n```\n\nFor more about using Alterior modules in Angular, see [@alterior/platform-angular](packages/platform-angular/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falterior-mvc%2Falterior","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falterior-mvc%2Falterior","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falterior-mvc%2Falterior/lists"}