# MJAPI Server ## Overview The MJAPI application is a thin wrapper around MemberJunction's server bootstrap. It starts an Apollo GraphQL server with auto-discovered resolvers. ## Entry Point (apps/MJAPI/src/index.ts) ```typescript import { createMJServer } from '@memberjunction/server-bootstrap'; import { RESOLVER_PATHS } from '@mj-biz-apps/common-server'; import '@memberjunction/server-bootstrap/mj-class-registrations'; createMJServer({ resolverPaths: RESOLVER_PATHS }).catch(console.error); ``` ## How It Works 1. `@mj-biz-apps/common-server` imports entities and actions, triggering @RegisterClass decorators 2. RESOLVER_PATHS points to generated GraphQL resolver files 3. `createMJServer()` from MJ bootstrap: - Connects to SQL Server (using .env credentials) - Loads MJ metadata - Registers all entity classes via class factory - Starts Apollo Server with resolvers - Listens on GRAPHQL_PORT (default 4101) ## Server Package (@mj-biz-apps/common-server) - Imports @mj-biz-apps/common-entities (triggers entity registration) - Imports @mj-biz-apps/common-actions (triggers action registration) - Imports generated GraphQL resolvers - Exports CLASS_REGISTRATIONS manifest - Exports RESOLVER_PATHS for dynamic loader - Exports LoadBizAppsCommonServer() bootstrap function ## GraphQL Schema Located at `apps/MJAPI/schema.graphql` (auto-generated by MJ). ### Key Query Types For each entity, MJ generates: - `Query.Get[EntityPlural]` - List with filtering, sorting, pagination - `Query.Get[Entity]ByID` - Single record by ID ### Key Mutation Types For each entity, MJ generates: - `Mutation.Create[Entity]` - Create new record - `Mutation.Update[Entity]` - Update existing record - `Mutation.Delete[Entity]` - Delete record ### Action Mutations - `Mutation.RunAction(input: RunActionInput!)` - Execute an MJ Action - `Mutation.RunEntityAction(input: EntityActionInput!)` - Execute an Entity Action ## Actions System Actions are server-side operations invoked via GraphQL: ### Invoking from Client ```typescript import { GraphQLActionClient } from '@memberjunction/graphql-dataprovider'; import { ActionParam } from '@memberjunction/actions-base'; const provider = Metadata.Provider as GraphQLDataProvider; const client = new GraphQLActionClient(provider); const result = await client.RunAction(actionID, [ { Name: 'PostalCode', Value: '10001', Type: 'Input' }, { Name: 'Country', Value: 'US', Type: 'Both' } ]); if (result.Success) { const data = JSON.parse(result.Message); } ``` ### Available Actions - **Postal Code Lookup**: Geocodes postal codes via Google Geocoding API, returns City and State ## Environment Configuration The server reads from `.env` at repo root: ```env DB_HOST=localhost DB_PORT=1433 DB_DATABASE=YourDatabase DB_USERNAME=sa DB_PASSWORD=yourpassword GRAPHQL_PORT=4101 # Authentication AUTH_TYPE=msal # ... MSAL or Auth0 settings # Optional: AI providers, SendGrid, etc. ``` ## Deployment ```bash cd apps/MJAPI npm run zip # Creates deploy.zip with node_modules, dist, package.json ``` ## Testing ```bash cd apps/MJAPI npm run test # Runs vitest ``` ## GraphQL Playground With the server running, navigate to `http://localhost:4101` to access the GraphQL playground for testing queries and mutations interactively. ## Data Provider Architecture - Client-side: GraphQLDataProvider implements MJ's DataProvider interface - Server-side: SQLServerDataProvider connects directly to SQL - Entity objects abstract the transport layer - same API works on both sides