Moonlight Architecture - The Old-New
Tags: php, pionia, webdev, restapi
Published: 2024-06-30 13:54:52

[Moonlight Architecture](https://pionia.netlify.app/moonlight/moonlight-architecture/) is an architecture that has existed for a while but remained nameless. Therefore, it is not right to say it is a new architecture yet most developers and companies have been using it. It borrows its features from commonly used architectures of MVC, gRPC, Graphql and Micro Services. Most of the features may highly sound, look more like MVC combined with Graphql.

## Features of Moonlight.

- REST only. Moonlight is meant for only REST applications. It does not support any form of templating. This is a design philosophy, whereby, it lets frontend frameworks handle frontend work while serving them APIs in the most elegant manner.

- Also Moonlight architecture is framework and language agnostic, implying that you can use it with your favourite framework in your favourite language. If you're coming from a PHP background, a framework - [Pionia](https://pionia.netlify.app), has already been put up to get you started, however, you can configure your favourite frameworks to work with this architecture. This has already been done with frameworks such as Spring Boot in Java(an excellent and pioneer framework for the architecture), Django Rest Framework in Python(worked excellently too) and Laravel in PHP(though some few features were not pulled off right).

- Moonlight encourages a single API endpoint for your entire API version, which means, all version APIs can be served at /api/v1/, then version two on /api/v2/. This is the only route you should have for your entire API. No query parameters, no relative paths but only one endpoint.

- Moonlight, encourages(enforces) all requests to the backend to be performed over POST. This has security benefits since the body of POST requests is usually logged while encrypted on a web server, thus keeping your requests secure to your application server.

- Single request format. The architecture encourages using either JSON or FormData if supported in your language or framework. Each request must define `SERVICE` and `ACTION` targeted. And the rest of the data as key-value pairs.
```JS
// POST https://exampleapi.com/api/v1/
{
  SERVICE: 'auth',
  ACTION: 'login',
  password: '1234567',
  username: 'moonlight'
}
```

- Single Response Format. The response must define the return code, return message, return data, and any extra data the server wants to communicate to the front end. In this case, the return code must be defined and by conventional, `0` is reserved for success, any other codes indicate failure but this can be customised to your business needs.

```js
// POST https://exampleapi.com/api/v1/
{
  returnCode: 0, // 0 for success, any other for error or warning
  returnObject: "token_here",// response data fro the server, can take any type according to the request
  returnMessage: 'Welcome back John Doe', // message you want the frontend to show
  extraData: null // any other data you want to pass.
}
```

- All requests that reach your application server must return a 200 OK status code whether they are resolved with an error or not. In cases of errors, a return code that is not `0` can be returned, with a clean, descriptive error message as the return message.

- Moonlight introduces the concept of switches, these represent a certain version of your API and register all services that are available in that version. Their main job is to read the incoming request, determine which service was defined and call it passing their entire request data. The switch also catches all uncaught exceptions in the request and returns a cleaner response similar to what we determined above.

- Services in Moonlight are central holders of your business logic, this is where you write all your actions specific to that service. An example of a service(class) can be `AuthService` that defines actions(methods) such as `login`, `resetPassword`, and `register`. All these must return the same response format. Actions are responsible for querying the database, validating the requested data and requesting any external third party that you might be integrating with.

## Known Issues With Architecture.

1. Strict(typed) languages such as Java, C# and Golang, may dictate you to stick to only JSON data. However, in non-strict languages like JS, Python, and PHP(which are commonly used for the web), you can mix both form data and JSON. This only affects uploading multipart files.

This is currently the only known issue so far affecting the architecture.

If you are interested in this architecture, you can [read more about it here](https://pionia.netlify.app/moonlight/moonlight-architecture/). Also, you can [try out Pionia for your next API application](https://pionia.netlify.app/documentation/introduction/#installation). Pionia provides full implementation of the architecture. You will be surprised how much you need to pull off an API!

Goodluck and happy coding!