Skip to main content
This guide provides a comprehensive reference for all configuration options in HGT EAM WebServices.

Configuration File Structure

The application uses appsettings.json as the primary configuration file. Environment-specific overrides can be placed in:
  • appsettings.Development.json
  • appsettings.Stage.json
  • appsettings.Production.json

Complete Configuration Template

appsettings.json
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "GridCache": "Data Source=gridcache.db"
  },
  "EAMBaseUrl": "https://your-eam-server/axis/services",
  "EAMCredentials": [
    {
      "Username": "eam-user",
      "Password": "eam-password",
      "Organization": "ORG_CODE"
    }
  ],
  "EAMGrids": [
    {
      "GridName": "WSJOBS",
      "UserFunction": "WSJOBS",
      "GridId": 123,
      "DataSpyIds": {
        "PreviousDay": 1001,
        "PreviousMonth": 1002,
        "CurrentMonth": 1003,
        "LastYear": 1004,
        "Custom": 1005,
        "AllRecords": 1000
      },
      "NumberRecordsFirstReturned": 500,
      "CursorPosition": 0,
      "HGTGridType": 1,
      "HGTGridName": 1,
      "FilterField": "CreationDate"
    }
  ],
  "EAMDefaultRecords": 100,
  "EnableAuthScheme": false,
  "ApiTitle": "HGT - Grid API",
  "ApiDescription": "API REST para acceder a las grillas de EAM de HGT",
  "Serilog": {
    "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft.AspNetCore": "Warning"
      }
    },
    "WriteTo": [
      {"Name": "Console"}
    ]
  },
  "AllowedHosts": "*",
  "GridCache": {
    "Enabled": true,
    "ExpirationMinutes": 60
  }
}

Connection Strings

GridCache

SQLite database connection string for the grid caching system.
{
  "ConnectionStrings": {
    "GridCache": "Data Source=gridcache.db"
  }
}
Parameters:
  • Data Source: Path to the SQLite database file (relative or absolute)
Examples:
// Relative path
"GridCache": "Data Source=gridcache.db"

// Absolute path
"GridCache": "Data Source=/var/lib/eam-api/gridcache.db"

// In-memory database (not recommended for production)
"GridCache": "Data Source=:memory:"
The application automatically adds a 30-second busy timeout to handle concurrent access during cold starts.

EAM Configuration

EAMBaseUrl

The base URL for INFOR EAM SOAP Web Services.
{
  "EAMBaseUrl": "https://your-eam-server/axis/services"
}
Type: string
Required: Yes
Format: Full URL including protocol
Examples:
"EAMBaseUrl": "https://eam.company.com/axis/services"
"EAMBaseUrl": "https://eam-prod.internal.network/axis/services"

EAMCredentials

Array of INFOR EAM user credentials used for Basic Authentication.
{
  "EAMCredentials": [
    {
      "Username": "string",
      "Password": "string",
      "Organization": "string"
    }
  ]
}
Schema:
HGT.EAM.WebServices.Infrastructure/Architecture/Models/EAMCredentialsSettings.cs
public sealed class EAMCredentialsSettings
{
    public string Username { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public string Organization { get; set; } = string.Empty;
}
Properties:
PropertyTypeRequiredDescription
UsernamestringYesEAM username
PasswordstringYesEAM password
OrganizationstringYesEAM organization code
Multiple Credentials Example:
{
  "EAMCredentials": [
    {
      "Username": "readonly_user",
      "Password": "secure_pass_1",
      "Organization": "MAINTENANCE"
    },
    {
      "Username": "admin_user",
      "Password": "secure_pass_2",
      "Organization": "ADMIN"
    }
  ]
}
Security Note: Store credentials securely. Consider using:
  • Azure Key Vault
  • AWS Secrets Manager
  • Environment variables
  • User Secrets (development only)
Example using environment variables:
export EAMCredentials__0__Username="myuser"
export EAMCredentials__0__Password="mypassword"
export EAMCredentials__0__Organization="ORG"

EAMGrids

Array defining the EAM grids exposed through the API.
{
  "EAMGrids": [
    {
      "GridName": "string",
      "UserFunction": "string",
      "GridId": 0,
      "DataSpyIds": {
        "PreviousDay": 0,
        "PreviousMonth": 0,
        "CurrentMonth": 0,
        "LastYear": 0,
        "Custom": 0,
        "AllRecords": 0
      },
      "NumberRecordsFirstReturned": 0,
      "CursorPosition": 0,
      "HGTGridType": 0,
      "HGTGridName": 0,
      "FilterField": "string"
    }
  ]
}
Schema:
HGT.EAM.WebServices.Infrastructure/Architecture/Models/EAMGridSettings.cs
public class EAMGridSettings
{
    public string GridName { get; set; } = string.Empty;
    public string UserFunction { get; set; } = string.Empty;
    public int GridId { get; set; }
    public DataSpyIds DataSpyIds { get; set; } = new DataSpyIds();
    public int NumberRecordsFirstReturned { get; set; }
    public int CursorPosition { get; set; }
    public HGTGridTypeEnum HGTGridType { get; set; }
    public HGTGridEnum HGTGridName { get; set; }
    public string FilterField { get; set; } = string.Empty;
}

public class DataSpyIds
{
    public int PreviousDay { get; set; }
    public int PreviousMonth { get; set; }
    public int CurrentMonth { get; set; }
    public int LastYear { get; set; }
    public int Custom { get; set; }
    public int AllRecords { get; set; }
}
Grid Properties:
PropertyTypeRequiredDescription
GridNamestringYesEAM grid identifier (e.g., “WSJOBS”)
UserFunctionstringYesEAM user function code
GridIdintYesNumeric grid identifier from INFOR EAM
DataSpyIdsobjectYesDataSpy IDs for time-based filters
NumberRecordsFirstReturnedintYesInitial batch size for fetching records
CursorPositionintYesStarting cursor position (usually 0)
HGTGridTypeintYesGrid type enum value
HGTGridNameintYesGrid name enum value
FilterFieldstringNoField name used for filtering
DataSpyIds Properties:
PropertyTypeDescription
PreviousDayintDataSpy ID for previous day filter
PreviousMonthintDataSpy ID for previous month filter
CurrentMonthintDataSpy ID for current month filter
LastYearintDataSpy ID for last year filter
CustomintDataSpy ID for custom date range
AllRecordsintDataSpy ID for all records
Complete Example:
{
  "EAMGrids": [
    {
      "GridName": "WSJOBS",
      "UserFunction": "WSJOBS",
      "GridId": 1234,
      "DataSpyIds": {
        "PreviousDay": 5001,
        "PreviousMonth": 5002,
        "CurrentMonth": 5003,
        "LastYear": 5004,
        "Custom": 5005,
        "AllRecords": 5000
      },
      "NumberRecordsFirstReturned": 1000,
      "CursorPosition": 0,
      "HGTGridType": 1,
      "HGTGridName": 1,
      "FilterField": "CreationDate"
    },
    {
      "GridName": "WSWORKORDERS",
      "UserFunction": "SSQMWO",
      "GridId": 5678,
      "DataSpyIds": {
        "PreviousDay": 6001,
        "PreviousMonth": 6002,
        "CurrentMonth": 6003,
        "LastYear": 6004,
        "Custom": 6005,
        "AllRecords": 6000
      },
      "NumberRecordsFirstReturned": 500,
      "CursorPosition": 0,
      "HGTGridType": 2,
      "HGTGridName": 2,
      "FilterField": "Status"
    }
  ]
}

EAMDefaultRecords

Default number of records to return per page when not specified in the request.
{
  "EAMDefaultRecords": 100
}
Type: int
Default: 100
Range: 1 - 10000

Grid Cache Configuration

Controls the SQLite-based grid caching system.
{
  "GridCache": {
    "Enabled": true,
    "ExpirationMinutes": 60
  }
}
Schema:
HGT.EAM.WebServices.Infrastructure/Architecture/GridCache/GridCacheOptions.cs
public class GridCacheOptions
{
    public const string SectionName = "GridCache";
    
    public bool Enabled { get; set; } = true;
    public int ExpirationMinutes { get; set; } = 60;
}
Properties:
PropertyTypeDefaultDescription
EnabledbooltrueEnable/disable grid caching
ExpirationMinutesint60Cache expiration time in minutes (0 = never expire)
Examples:
// Cache enabled with 2-hour expiration
{
  "GridCache": {
    "Enabled": true,
    "ExpirationMinutes": 120
  }
}

// Cache disabled (always fetch from EAM)
{
  "GridCache": {
    "Enabled": false,
    "ExpirationMinutes": 0
  }
}

// Cache never expires
{
  "GridCache": {
    "Enabled": true,
    "ExpirationMinutes": 0
  }
}
Performance Impact:
  • Enabled: Fast responses for cached data, reduced EAM load
  • Disabled: Always fresh data, increased EAM load
  • Long expiration: Better performance, potentially stale data
  • Short expiration: Fresher data, more frequent EAM calls

Logging Configuration (Serilog)

The application uses Serilog for structured logging.

Basic Configuration

{
  "Serilog": {
    "Using": ["Serilog.Sinks.Console", "Serilog.Sinks.File"],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft.AspNetCore": "Warning",
        "Microsoft.Hosting.Lifetime": "Warning",
        "Microsoft.EntityFrameworkCore": "Warning"
      }
    },
    "WriteTo": [
      {"Name": "Console"}
    ],
    "Properties": {
      "Application": "HGT.EAM.WebServices"
    }
  }
}

Log Levels

LevelDescriptionUse Case
VerboseMost detailedDebugging only
DebugDetailed diagnosticDevelopment
InformationGeneral flowProduction (default)
WarningAbnormal/unexpectedProduction
ErrorErrors/exceptionsAlways log
FatalCritical failuresAlways log

Filtering API Logs

The application includes a filter to only log API requests:
{
  "Serilog": {
    "Filter": [
      {
        "Name": "ByIncludingOnly",
        "Args": {
          "expression": "Contains(RequestPath, '/api') or @Level = 'Error'"
        }
      }
    ]
  }
}
This configuration:
  • Logs all requests to /api/* endpoints
  • Always logs errors regardless of path
  • Ignores requests to /scalar, /openapi, etc.

Console Sink

{
  "WriteTo": [
    {"Name": "Console"}
  ]
}

File Sink

{
  "WriteTo": [
    {
      "Name": "File",
      "Args": {
        "path": "logs/eam-api-.txt",
        "rollingInterval": "Day",
        "retainedFileCountLimit": 30,
        "outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}"
      }
    }
  ]
}

SQL Server Sink

{
  "Using": ["Serilog.Sinks.MSSqlServer"],
  "WriteTo": [
    {
      "Name": "MSSqlServer",
      "Args": {
        "connectionString": "LogDatabase",
        "tableName": "Logs",
        "autoCreateSqlTable": true,
        "restrictedToMinimumLevel": "Information"
      }
    }
  ]
}

Enrichment

The application automatically enriches logs with:
HGT.EAM.WebServices/Setup/Program.cs
builder.Host.UseSerilog((context, configuration) =>
    configuration
        .ReadFrom.Configuration(context.Configuration)
        .Enrich.FromLogContext()
);
Logged properties include:
  • RequestPath: Request URL path
  • CurrentUser: Authenticated username or “Anonymous”
  • QueryString: Query parameters
  • Method: HTTP method
  • StatusCode: Response status code
  • Elapsed: Request duration

API Documentation Configuration

ApiTitle & ApiDescription

Configures the OpenAPI/Scalar documentation metadata.
{
  "ApiTitle": "HGT - Grid API",
  "ApiDescription": "API REST para acceder a las grillas de EAM de HGT. Internamente consume los servicios SOAP de EAM."
}

EnableAuthScheme

Controls whether to show the authentication scheme in the OpenAPI documentation.
{
  "EnableAuthScheme": false
}
Values:
  • false (default): Basic OpenAPI documentation without auth UI
  • true: Shows Basic Auth input fields in Scalar UI

ASP.NET Core Configuration

AllowedHosts

Specifies which hosts are allowed to access the application.
{
  "AllowedHosts": "*"
}
Examples:
// Allow all hosts (development)
"AllowedHosts": "*"

// Specific domains only (production)
"AllowedHosts": "eam-api.company.com;api.company.com"

Logging (ASP.NET Core)

Standard ASP.NET Core logging configuration (used alongside Serilog).
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Rate Limiting Configuration

Rate limiting is configured in code but can be customized:
HGT.EAM.WebServices/Setup/Startup.cs
services.AddRateLimiter(options =>
{
    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
    
    options.AddPolicy("api", httpContext =>
    {
        // 60 requests per minute per user/IP
        return RateLimitPartition.GetFixedWindowLimiter(
            partitionKey: key,
            factory: _ => new FixedWindowRateLimiterOptions
            {
                PermitLimit = 60,
                Window = TimeSpan.FromMinutes(1),
                QueueLimit = 0,
                AutoReplenishment = true
            });
    });
});
See the Rate Limiting Guide for detailed information.

Environment Variables

All configuration can be overridden using environment variables:
# Format: Section__Property or Section__Index__Property
export EAMBaseUrl="https://eam-prod.company.com/axis/services"
export EAMCredentials__0__Username="produser"
export EAMCredentials__0__Password="prodpass"
export GridCache__ExpirationMinutes="120"
export Serilog__MinimumLevel__Default="Warning"

Configuration Validation

The application validates configuration at startup:
HGT.EAM.WebServices/Setup/ServiceCollectionExtensions.cs
public static IServiceCollection AddApplicationServices(
    this IServiceCollection services, IConfiguration configuration)
{
    var gridSettings = configuration.GetSection("EAMGrids");
    
    if (!gridSettings.Exists())
        throw new InvalidOperationException(
            "EAMGrids configuration section is missing.");
    
    var allGrids = configuration.GetSection("EAMGrids")
        .Get<List<EAMGridSettings>>();
    
    if (allGrids == null || allGrids.Count == 0)
        throw new InvalidOperationException(
            "EAMGrids configuration section is missing or empty.");
    
    // ... rest of configuration
}

Next Steps

Setup Guide

Complete setup and installation guide

Rate Limiting

Understanding rate limiting

Build docs developers (and LLMs) love