MSNGR

command module
v0.0.0-...-a02f58f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2024 License: MIT Imports: 10 Imported by: 0

README

MSNGR

Regarding the exercise

I decided to use a synchronous API for the sake of time and complexity as described in the task. Optimally we would add the messages to a queue and respond with a hypermedia-api-response including a link to request the status of a forwarded-message since the calls to the communication-provider can vary in execution time.

The response for such an api could've looked something like this in an async case

{
  "data": {
    "information": "Request was accepted"
  },
  "links": {
    "status": "/messages/{myuniqueId}/status"
  }
}

Additionally I built the system enhanceable in the areas where I saw the most potential: "Rules for forwarding the message" and "channels to send it to".

For testing: The integration tests will fail if the .env file is not present in the right directory or the env variables are not set. I focused on integration tests since I felt the exercise implied that.

I also skipped graceful shutdown of the api server for time's-sake (can be done by listeing to the signals from the cli)

Documentations

Used Packages

Gin -> Webframework. Has to be checked for a proper application since it uses unstable packages

Zerolog -> Logging (in this case only console logging)

Google's UUID -> UUID Generation for tracing.

Could've been used

Google's Wire -> Dependency Injection via Code Generation

"swaggo/swag" -> OpenAPI Document Generation

Opentelemetry -> Metrics & Tracing

Implementation Details

The application is a synchronous API built on a somewhat "clean" architecture. The request enters through a controller MessageController which has a dependency on a struct that holds business logic called ForwardingProvider with additional dependencies on ForwardingRules. The ForwardingProvider executes the rule that was injected in the "constructor" whenever there is a message that might need forwarding. The default ForwardingRule filters for the message type being Warning and also filters on the discord CommunicationProvider (CP). It returns a potentially reduced list of CPs to the ForwardingProvider which then commands all of them to send the messages via their specific channels.

Enhancements
New Channels

Other channels besides discord can be added by simply adding implementations of CommunicationProvider and adding them via DependencyInjection. To have them actively used, the ForwardingRule needs to keep them in the filtered return value.

Customer-Specific Rules

Adding customer specific rules might be a bit more difficult since one has to introduce a database that contains the rules for a customer. It also depends on the complexity of the rules. But besides a storage for the custom rules we only need a different implementation of ForwardingRule. We could have a factory that creates a rule per customer or a dynamic rule that actively retrieves it's configuration from the database per request.

API Definition

(For a proper application i recommend code generated API definitions e.g. OpenAPI)

Request

POST http://localhost:6616/api/{customerId}/messages for local development

{
  "Type": "String e.g. 'Warning'",
  "Name": "String",
  "Description": "String"
}
Responses

Validation Error (400)

{
  "Data": null,
  "Errors": [
    {
      "Id": "uuid",
      "Detail": "string"
    }
  ]
}

Unkown Error (500)

{
  "Data": null,
  "Errors": [
    {
      "Id": "uuid",
      "Detail": "string"
    }
  ]
}

No Provider found (200)

{
  "Data": {
    "Description": "string"
  },
  "Errors": []
}

Forwarded (204)

<empty>

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL