This API project provides a robust interface for accessing and managing uncompiled mhfdat.bin data.
Designed with scalability and maintainability in mind, the API is organized following clean architecture principles. It features well-defined controllers for handling requests, middlewares for tasks such as logging and routing, models to represent data structures, and utility functions for seamless integration with tools like New Relic.
This structure ensures efficient request handling, extensibility, and ease of development while maintaining performance and monitoring capabilities.
git clone https://github.com/mezelounge/mhf-api.git
go mod download
Don't forget to change the configuration.
To run the API, execute:
go build . && ENVIRONMENT=dev go run .
Here are some example endpoints:
/items
: Fetch all items./items/{id}
: Fetch a specific item by ID.The project is organized as follows:
mhf-api/
├── config/ # 🔧 Where all configurations files are
| |
| ├── dev/ # 💻 Configurations for the development environment
| | ├── base.json
| | ├── launcher.json
| | ├── locales.json
| | ├── logger.json
| | ├── mhfdat.json
| | └── newrelic.json
| |
| ├── prod/ # 🏢 Configurations for the production environment
| | ├── base.json
| | ├── launcher.json
| | ├── locales.json
| | ├── logger.json
| | ├── mhfdat.json
| | └── newrelic.json
| |
| └── index.go # 🚀 Initializes configurations based on the environment
|
├── core/ # 💡 Contains the core logic of the API
| └── index.go # ⚙️ Core of the application (main logic)
|
├── server/ # 🌐 Handles all server-related functionalities (routes, middleware)
| |
| ├── common/ # 📦 Shared code for various parts of the server
| |
| ├── launcher/
| | |
| | ├── controllers/ # 🕹️ Folder for request handlers and business logic
| | | ├── check.go
| | | └── files.go
| | |
| | ├── middlewares/ # 🔗 Contains middleware functions (logging, routing, etc.)
| | | ├── check.go
| | | └── files.go
| | |
| | ├── views/ # 🪟 Contains middleware functions (logging, routing, etc.)
| | | └── files.go
| | |
| | └── index.go # 🌳 Expose routes and router
| |
| ├── mhfdat/
| | |
| | ├── controllers/ # 🕹️ Folder for request handlers and business logic
| | | ├── equipments.go
| | | ├── item.go
| | | ├── quest.go
| | | ├── quest.go
| | | ├── weapon_melee.go
| | | └── weapon_ranged.go
| | |
| | ├── middlewares/ # 🔗 Contains middleware functions (logging, routing, etc.)
| | | ├── equipments.go
| | | ├── item.go
| | | ├── quest.go
| | | ├── quest.go
| | | ├── weapon_melee.go
| | | └── weapon_ranged.go
| | |
| | ├── models/ # 📚 Contains middleware functions (logging, routing, etc.)
| | | ├── equipments.go
| | | ├── item.go
| | | ├── quest.go
| | | ├── quest.go
| | | ├── weapon_melee.go
| | | └── weapon_ranged.go
| | |
| | ├── shared/ # 🗂️ Contains middleware functions (logging, routing, etc.)
| | | └── index.go
| | |
| | └── index.go # 🌳 Expose routes and router
| |
| ├── index.go # 🚀 Initialize the server
| ├── launcher.go # 📍 Generate the router
| ├── logger.go # 📝
| └── mhfdat.go # 📍 Generate the router
|
├── utils/ # 🛠️ Folder for utility functions (logging, ASCII art, New Relic)
| ├── ascii/ # 🎨 Contains ASCII art template shown when the server starts
| ├── binary/ # 🗂️ Utility functions for handling binary files
| ├── logger/ # 📝 Initialization and configuration of the logging system
| ├── newrelic/ # 📊 Functions for New Relic integration and performance monitoring
| └── pointers/ # 📌 List and declaration of pointers to access data
|
└── main.go # 🚪 Main entry point of the application where everything is initialized
The API configuration is handled through the config
package. It uses viper
to manage configuration files for different environments (e.g., dev
, prod
) and sets up key application settings, such as the server host, logging, MHF data file paths, and New Relic integration.
Within the config/
directory, there are subdirectories for each environment (e.g., dev/
and prod/
)
When the API starts, it loads the appropriate configuration based on the environment (defined by the ENVIRONMENT
variable). The configuration loader fetches the relevant JSON files, decodes them, and merges their values into the global Config
struct.
Here's a breakdown of the Config
struct:
type Config struct {
Host string // The server host (automatically detected if not set)
Port string // The port the server listens on
Logger Logger // Logger configuration
Mhfdat Mhfdat // MHF data file path
NewRelic NewRelic // New Relic settings
}
type Info struct {
FilePath string // FilePath
Enable bool // To enable or disable the router linked
}
type Launcher struct {
En Info // LauncherInfo for En version
Fr Info // LauncherInfo for Fr version
Jp Info // LauncherInfo for Jp version
}
type Mhfdat struct {
En Info // MhfdatInfo for En version
Fr Info // MhfdatInfo for Fr version
Jp Info // MhfdatInfo for Jp version
}
type Logger struct {
Format string // Logging format (e.g., JSON or text)
FilePath string // File path for log output
}
type NewRelic struct {
License string // New Relic license key
AppName string // Application name for monitoring in New Relic
AppLogForwardingEnabled bool // Whether log forwarding is enabled
}
When the application starts, it uses the LoadConfig
function to load configurations for the environment:
func LoadConfig(env string) (*Config, error) {
var config Config
config_files := []ConfigFile{
{Name: "base"},
{Name: "launcher"},
{Name: "locales"},
{Name: "logger"},
{Name: "mhfdat"},
{Name: "newrelic"},
}
viper.SetConfigType("json")
path := fmt.Sprintf("./config/%s", env)
viper.AddConfigPath(path)
for _, config_file := range config_files {
viper.SetConfigName(config_file.Name)
if err := viper.ReadInConfig(); err != nil {
return nil, err
}
if err := viper.Unmarshal(&config); err != nil {
return nil, err
}
}
if config.Host == "" {
config.Host = getOutboundIP4().To4().String()
}
return &config, nil
}
Example of a base.json
file (for general settings):
{
"host": "127.0.0.1",
"port": ":8080"
}
Example of a logger.json
file:
{
"format": "json",
"filePath": "./logs/app.log"
}
Example of a launcher.json
file:
{
"Launcher": {
"En": {
"FilePath": "/path/to/game_folder",
"Enable": false
},
"Fr": {
"FilePath": "/path/to/game_folder",
"Enable": false
},
"Jp": {
"FilePath": "/path/to/game_folder",
"Enable": false
}
}
}
Example of a mhfdat.json
file:
{
"Mhfdat": {
"En": {
"FilePath": "/path/to/mhfdat.bin",
"Enable": false
},
"Fr": {
"FilePath": "/path/to/mhfdat.bin",
"Enable": false
},
"Jp": {
"FilePath": "/path/to/mhfdat.bin",
"Enable": false
}
}
}
Example of a newrelic.json
file:
{
"license": "your-new-relic-license-key",
"appName": "MHF-API",
"appLogForwardingEnabled": true
}
The entry point is in main.go
, where the application initializes the logger and New Relic monitoring, and starts the server:
Init()
function from the server
package, which binds the router and applies middleware.The server.Init()
function handles:
Listening: The server listens for incoming HTTP requests
on the configured port.
http://localhost:9999/en/mhfdat/equipments/helm?limit=2&page=2
http://localhost:9999/en/launcher/files
This file manages item-related endpoints:
List
: Returns a list of all data.Read
: Fetches a specific data by its ID./items
: Returns all items./items/{id}
: Returns a specific item by ID.Middlewares are defined in middlewares/
:
GetRouterItem()
defines the routes for item-related API requests.user.go
) can be added as needed for other features.The models/item.go
file defines the Item
struct:
type Item struct {
ID int `json:"id"`
Name string `json:"name"`
}
This model is used to represent items across the API.
Feel free to submit issues or pull requests to improve the API or add new features. Contributions are always welcome!
This project is licensed under the MIT License.