Skip to content
Mikhail Deriabin edited this page Jan 9, 2025 · 14 revisions

Intro to API

_id field

The _id field is unique and auto-generated by the API, which can not be changed = read-only. This field is used in cases there is a need of identifying an object, such as reading, updating, and deleting object information, as well as in foreign fields and arrays inside an object, which names contain an "_id"-part (clan_id, player_id).

This field is a MongoDB _id, and it is guaranteed to be unique. This field is always a string and cannot be null, undefined, etc.

Foreign fields

A foreign field is an _id field which links different objects together. For example, a Player can join a Clan, so the Player object will have a clan_id field, which is a foreign field. The name of a foreign field always starts with the name of the object (=collection) to which it is pointing (=belongs).

For example, clan_id = _id of the Clan to which a particular collection belongs, so if a Player object has a clan_id, it means that the Player belongs to (=joined) the Clan, or if Soulhome has a clan_id field, it means that Soulhome belongs to the Clan.

Collection

A collection is an abstraction representing one data structure (=object). It is the same thing as a class having a concrete implementation - object. Basically, a collection is a table in SQL terms.

Collections' relations

One collection may belong to another. In cases where only one object can belong to another one, or one object may have only one other object, it is called a one-to-one relation. For example, Soulhome may belong to only one Clan, or one Clan may have only one Soulhome. This kind of relation is called one-to-one.

Another relation is one-to-many. For example, multiple Players may belong to one Clan, or one Clan may have multiple Players.

The third and last relation is many-to-many. This relation is not yet used in the current version of the API, but the idea is the same as the previous ones. An A-object may belong to many B-objects, or a B-object may have many A-objects.

ER diagram

Below is an ER diagram, which shows all collections that can be manipulated via the API and are stored in the database. On the diagram, fields for each collection can be found except for foreign fields. The underlined fields are fields with unique values.

The diagram also shows the relations between collections, represented by a line with a rhombus in the middle. On the end of each line, one or two symbols can be found. The symbol closer to the collection represents the relation:

  1. One line means that only one object might belong to the opposite collection. For example, a Player may belong to only one Clan.
  2. The three lines symbol means that the opposite collection may have multiple objects. For example, a Clan may have multiple Players.
  3. These two symbols on each line represent the relation between collections. For example, Clan to Player - one-to-many, Clan to Soulhome - one-to-one.

The second symbol, farther from the collection, represents whether the relation is mandatory or optional: line - mandatory and 0 - optional. For example, the Player may or may not belong to a Clan, but Soulhome must belong to a Clan.

Database ER diagram

Relations impact on API use

As mentioned previously, relations can be mandatory or optional. This may affect the logic of how objects can be created or deleted. For example, before it is possible to create a Soulhome, there must be a Clan to which it will belong because the Soulhome cannot exist on its own and relation is mandatory. At the same time, a Clan can be created without a Soulhome existing. In the case of mandatory relations, one part always must be optional. However, it is also possible that both sides of the relation are optional; in this case, there are no restrictions, and the order of creation does not matter.

In the case of deleting an object, some restrictions may also be applied based on the relation between collections. In the case of Clan - Soulhome, the Soulhome can be deleted without any additional actions, but if there is a need to delete the Clan, all mandatory objects must be deleted first. So, the Soulhome must be deleted first, and only after that can the Clan be deleted.

Both creation and deletion logic can be done manually by multiple requests. So, if there is a need to delete a Clan, the Soulhome must be deleted on the first request, and after that, the Clan can be deleted. It is possible that the API handles this logic automatically (not always the case), and it is important to keep in mind that the creation and deletion may have side effects.

API requests

The Altzone API is a REST API, which means that it follows REST architecture principles. The conventions of REST are providing an interface for making similar requests for any endpoint, and for example retrieving information process for Clan and Player objects is the same.

Data manipulation, CRUD

The REST API’s main task is to manipulate the data. The data manipulation can be divided into four types: Creation, Reading, Updating, Deleting, also known as CRUD. These are the actions, which one can do with data.

Resources and endpoints

One of the main concepts in the REST is a resource. Basically, it is a collection, for example Clan or Player. For each resource there are an endpoint in an API. The name must be the same as a resource name, so for the Player there are /player endpoint. The ER diagram is showing collections and represents the database structure, but it also can be used as a reference for endpoints existing in the API.

HTTP protocol and REST

The REST is meant to be used with the HTTP protocol. This is one of the most used protocols on the Internet. REST uses parts of this protocol. One part is the endpoint, as discussed before, for representing a certain resource. Another part is the HTTP method, which describes what kind of action needs to be made. For example, if one wishes to read Player data, they should use the GET method and /player endpoint. For CRUD operations, these methods are used:

  1. POST Creating
  2. GET Reading
  3. UPDATE Updating
  4. DELETE Deleting

HTTP request structure

There are two parts of request and response in HTTP protocol: headers and body.

Headers contain metadata used for proper data transition, security, or any custom data defined by the API. One header is a key-value pair, where the key must be unique and the value usually is a string or a number (not necessarily). For the HTTP request, not many headers must be defined manually by the programmer; usually, the library for HTTP requests handles a big part of them. However, the Content-Type header with the application/json value must be specified for all POST and PUT requests (requests with a body).

The body part is used for sending data to an API. For example, if one is creating a new Player, they should put the new Player data in the body of the request. For this API, the JSON format is used in all such requests, which is why the Content-Type header must have the application/json value. Notice that the body is only needed when some data should be sent (creating or updating). When there is nothing to send (reading or deleting), there is no body specified.

HTTP response structure

The response structure is the same as the request. It also has headers and a body. On deletions, updates, and in some cases of errors, there will be usually no body sent.

Parameters and queries

The URL of a request can contain parameters and queries. These are dynamic values of the URL, usually providing additional data for the requests.

A parameter is a dynamic value at the end of the endpoint, but not after the query. For example, /clan/651d5a500d067b29208403f7. Here, at the end, the Clan _id is added, and if a GET request is made to that endpoint, the data about the Clan with this _id is returned. In this API, parameters are used only for specifying the _id of some object.

A query is a dynamic value used usually for additional settings of the response. The query always starts with a question mark and is put at the very end of the URL. Notice that it cannot be placed in the middle of the URL, even before a parameter. The query is a string of key-value pairs, where these pairs are separated with '&'.

Examples of valid query strings:

  1. /clan?limit=10 one pair
  2. /clan?limit=10&sort=name two pairs (separated by &)
  3. /clan?desc one pair (desc has no value, used with boolean values: if specified => true, if not => false)
  4. /clan?desc= also correct form of the previous

Notice that all values in pairs are strings, which means there is no need to add "- or '- or `-symbols, as they are treated as part of the value.

HTTP status codes

Status codes are used to indicate the response status or result of a request. For example, if no Clans are found, the 404 code will be returned. In this API, the following status codes can be returned:

Code Meaning
200 Request succeeded
201 Created successfully (for POST only)
204 Request succeeded, no body in response
400 Bad request in general
401 Not authenticated = no Authorization header provided (more on that later)
403 Not authorized = no rights to perform the request
404 Not found (for GET only)
409 Field not unique (for POST and PUT only)
500 Unexpected server error. Please add a new issue in the Issues tab about it

API errors

The API might return errors as a response. These errors might arise as a result of wrong request or due to unexpected errors on API.

The request errors can be divided into groups:

  1. Validation
  2. Field uniqueness
  3. Authentication and authorization
  4. Not found

The validation errors arise, when some required field is not specified in the body or the field data type is wrong. For example if for a new Clan name-field is not specified or its value is 23 instead of some string value, validation error will be returned. These errors can and should be avoided by validation before request is being sent.

The field uniqueness errors happen, when the object with that field value already exists. For example the name-field of Clan must be unique, so in case if the Clan with name "clan1" already exists this error will be returned. These errors can not be avoided before request, however since all unique fields are predefined, such errors should be taken into account.

The authentication is a process of identifying by whom request is being made, usually profile username or email is used for that. This error is rare and might happen when the user is not logged-in or his identifier is expired (more on that later), in this case the user should be asked to login to the system.

The authorization is a process of identifying does the user has a permission for the request. It relies on the successful authentication, which determines who is logged-in. In this API the rule-based authorization approach is used. The API determine rules for each user individually, which provides more flexibility compared to role-based approach. The rules are predefined and errors related to authorization should be prevented, for example if user is not admin of the Clan and he can not delete the Clan, then the "Delete Clan"-button should not be displayed for the user. More about that later.

Not found errors are simply errors, when nothing is found for the request. For example if there are no Clan objects created yet or if user is trying to delete Clan by non-existing _id. These errors are happening usually only on GET and DELETE requests. Such errors is not possible to prevent, but they should be taken into account, for example by showing a message to the user that no Clans are found.