DAI-Practical-Work-3

This project was realized by Dylan Langumier, Guillaume Fragnière and Killian Viquerat in the scope of the DAI class, followed at HEIG-VD.


Table of Contents

  1. Purpose
  2. Setup Development WorkPlace
  3. Docker
  4. API
  5. How to use
  6. Web infrastructures

Purpose

This web application allows you to host an API. This API is based on the Binding Of Isaac game. It procures functionality to manipulate item and characters.

You can find the API documentation here


Setup Development WorkPlace

Prerequisite

This application was built against Temurin 21, and thus requires Temurin 21+ to run.

Clone

First you need to clone the project. You can use this command:

git clone git@github.com:Dylan-Langumier/DAI-Practical-Work-3.git

Or by downloading the source code and then unzipping in into a directory.

How to build

From Intellij IDEA

Use the Run the application configuration

From your CLI

If you have Maven installed

mvn dependency:go-offline clean compile package

If you do not have Maven, we included a Maven Wrapper, which you can use to build the application:

./mvnw dependency:go-offline clean compile package

Docker

Create the image, the tag and push it to ghcr.io

Warning

Please note that bofore running docker build you need to have cloned and built the application using Maven first.

Note

If you would like to open a Pull Request in order not to require having to build the application beforehand and let Docker do it on its own, you are more than welcome to!

docker build -f Dockerfile -t tboi .
docker tag tboi ghcr.io/dylan-langumier/tboi:latest
docker push ghcr.io/dylan-langumier/tboi:latest

This allows to then pull it as an image in the Docker Compose file with the following line

  image: ghcr.io/dylan-langumier/tboi:latest

Docker Compose specifics

The Docker Compose file contains a network, marked as external (meaning it doesn't create it, it just tried ) it connects to, which is for Traefik. The Docker Compose of that service is not included, however you can find it here.

How to run the API

You have multiple options to run the API. Either you curl/download the Docker Compose File from this repository then run it.

curl https://raw.githubusercontent.com/Dylan-Langumier/DAI-Practical-Work-3/refs/heads/master/docker-compose.yml -O
docker compose up -d

Or you clone the repository and run the same Docker Compose File.

git clone git@github.com:Dylan-Langumier/DAI-Practical-Work-3.git
cd DAI-Practical-Work-3 && docker compose up -d

API

The TboI API allows to get items or characters from the game The Binding of Isaac. It uses the HTTP protocol and the JSON format.

The API is based on the CRUD pattern. It has the following operations:

  • Create a new item/character
  • Get many items that you can filter by first item pool or quality
  • Get many characters
  • Get one item by its id
  • Update an item/character
  • Delete an item/character

Users are also able to get a random item from a given item pool or given quality.

Endpoints

Get many items

  • GET /items

Get all items from the database.

Request

None.

Response

The response body contains a JSON array with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Returns all the items
  • 304 (Not Modified) - The items have not been modified since the last access, so they are retrieved through cache

Get one item

  • GET /item/{id}

Get one item by its id.

Request

The request must contain the following query parameters:

  • id - The id of the item (of the form cXXX)

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Returns the desired item
  • 304 (Not Modified) - The item has not been modified since the last access, so it is retrieved through cache
  • 404 (Not Found) - The item with the given id was not found

Get all items by quality

  • GET /items/quality/{quality}

Get all items of a given quality.

Request

The request path must contain the desired quality.

Response

The response body contains a JSON array with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Returns all the items
  • 304 (Not Modified) - The items of the quality have not been modified since the last access, so they are retrieved through cache

Get all items by pool

  • GET /items/pool/{pool}

Get all items of a given pool.

Request

The request path must contain the desired pool.

Response

The response body contains a JSON array with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Returns all the items

Get a random item

  • GET /items/d6

Get a random item.

Request

Empty.

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Return a random item

Get a random item from a given quality

  • GET /items/d6/{quality}

Get a random item from a given quality.

Request

The request path must contain the desired quality.

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Return a random item from the given quality
  • 404 (Not Found) - The quality is invalid

Get a random item from a given pool

  • GET /items/d6/{pool}

Get a random item from a given pool.

Request

The request path must contain the desired poll.

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - Return a random item from the given quality
  • 404 (Not Found) - The pool is invalid

Spindown an item

  • GET /item/spindown/{id}

Gets the item with an id of 1 lower than the given id.

Request

The request path must contain the desired item's id.

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Note that the response can be a null object, if the item has no spindown (id c1) or if the given id is not a valid item.

Status codes

  • 200 (OK) - Return a random item from the given quality

Create a new item

  • POST /item/{id}

Create a new item.

Request

The request body must contain a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 201 (Created) - The user has been successfully created
  • 409 (Conflict) - The given item id is already taken

Update an item

  • PATCH /item/{id}

Update an item by its id.

Request

The request path must contain the id of the item.

The request body must contain a JSON object with the following properties:

  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Response

The response body contains a JSON object with the following properties:

  • id - The id of the item
  • name - The name of the item
  • type - The type of the item
  • itemPools - An array of the item pools the item is in
  • statistics - An array of JSON arrays containing the statistics modifiers of the item.
  • description - The text description rendered on item pickup
  • quality - The quality of the item
  • gameVersions - The version of the game the item was introduced in
  • note (optional) - A note on the item that can contain trivia or item effect info

Status codes

  • 200 (OK) - The item has been successfully updated
  • 404 (Not Found) - The item does not exist

Delete an item

  • DELETE /item/{id}

Delete an item by its id.

Request

The request path must contain the id of the item.

Response

The response body is empty.

Status codes

  • 204 (No Content) - The item has been successfully deleted
  • 404 (Not Found) - The item does not exist

Get many characters

  • GET /characters

Get all characters from the database.

Request

None.

Response

The response body contains a JSON array with the following properties:

  • id - The id of the character
  • name - The name of the character
  • hearts - The starting hearts of the character - can be red, soul, black or bone hearts
  • damage - The starting damage of the character
  • shotSpeed - The starting shot speed of the character
  • range - The starting range of the character
  • speed - The starting speed of the character
  • luck - The starting luck of the character
  • startingPickups - The starting pickups of the character (bombs, keys, pennies)
  • startingItems - The starting items of the character

Status codes

  • 200 (OK) - Returns all the characters
  • 304 (Not Modified) - The characters have not been modified since the last access, so they are retrieved through cache

Get one item

  • GET /character/{id}

Get one character by its id.

Request

The request must contain the following query parameters:

  • id - The id of the item

Response

The response body contains a JSON object with the following properties:

  • id - The id of the character
  • name - The name of the character
  • hearts - The starting hearts of the character - can be red, soul, black or bone hearts
  • damage - The starting damage of the character
  • shotSpeed - The starting shot speed of the character
  • range - The starting range of the character
  • speed - The starting speed of the character
  • luck - The starting luck of the character
  • startingPickups - The starting pickups of the character (bombs, keys, pennies)
  • startingItems - The starting items of the character

Status codes

  • 200 (OK) - Returns the desired character
  • 304 (Not Modified) - The character has not been modified since the last access, so it is retrieved through cache
  • 404 (Not Found) - The character with the given id was not found

Update a character

  • PATCH /character/{id}

Update an character by its id.

Request

The request path must contain the id of the character.

The request body must contain a JSON object with the following properties:

  • name - The name of the character
  • hearts - The starting hearts of the character - can be red, soul, black or bone hearts
  • damage - The starting damage of the character
  • shotSpeed - The starting shot speed of the character
  • range - The starting range of the character
  • speed - The starting speed of the character
  • luck - The starting luck of the character
  • startingPickups - The starting pickups of the character (bombs, keys, pennies)
  • startingItems - The starting items of the character

Response

The response body contains a JSON object with the following properties:

  • id - The id of the character
  • name - The name of the character
  • hearts - The starting hearts of the character - can be red, soul, black or bone hearts
  • damage - The starting damage of the character
  • shotSpeed - The starting shot speed of the character
  • range - The starting range of the character
  • speed - The starting speed of the character
  • luck - The starting luck of the character
  • startingPickups - The starting pickups of the character (bombs, keys, pennies)
  • startingItems - The starting items of the character

Status codes

  • 200 (OK) - The character has been successfully updated
  • 404 (Not Found) - The character does not exist

Delete an item

  • DELETE /character/{id}

Delete a character by its id.

Request

The request path must contain the id of the character.

Response

The response body is empty.

Status codes

  • 204 (No Content) - The character has been successfully deleted
  • 404 (Not Found) - The character does not exist

How to use

Query All Items

  • Command:
curl -i -X GET https://localhost:8080/items
  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 12:54:53 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T13:54:53.264587946
Content-Length: 11150

[{"id":"c362","name":"Sworn Protector","type":"Passive","statistics":[],"description":"Protective friend","itemPools":["BabyShop","AngelRoom"],"quality":3,"gameVersions":["Afterbirth"],"note":"An orbital angel which does 7 contact damage per tick and blocks shots."},
{"id":"c11","name":"1up!","type":"Passive","statistics":[],"description":"Extra life","itemPools":["SecretRoom"],"quality":2,"gameVersions":["Flash"],"note":"Gives Isaac an extra life."}
]

Only part of the body because it would be too big otherwise


Query All Items by Pool

Available Pools
  • AngelRoom
  • BabyShop
  • BatteryBum
  • Beggar
  • BombBum
  • Boss
  • CraneGame
  • CurseRoom
  • DevilBeggar
  • DevilRoom
  • GoldenChest
  • KeyMaster
  • Library
  • MomsChest
  • OldChest
  • Planetarium
  • RedChest
  • RottenBeggar
  • SecretRoom
  • ShellGame
  • Shop
  • TreasureRoom
  • UltraSecretRoom
  • WoodenChest
  • Command:
curl -i -X GET https://localhost:8080/items/pool/TreasureRoom

Example with TreasureRoom Pool

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:20:30 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T14:20:30.470678908
Content-Length: 8807

[{"id":"c670","name":"Montezuma's Revenge","type":"Passive","statistics":[],"description":"Oh no...","itemPools":["TreasureRoom"],"quality":2,"gameVersions":["Repentance"],"note":"While firing tears, you now charge up a poop attack for 3 seconds that when released, fires from Isaac's behind."},
{"id":"c222 ","name":"Anti-Gravity","type":"Passive","statistics":[{"type":"TearRate","value":"+1","gameVersions":null}],"description":"Anti-gravity tears + tears up","itemPools":["TreasureRoom"],"quality":1,"gameVersions":["Rebirth"],"note":"Holding the fire buttons causes tears to hover in midair. When released, the tears will all shoot in the direction they were originally fired."}
]

Only part of the body because it would be too big otherwise


Query All Items by Quality

  • Command:
Available Qualities
  • 0
  • 1
  • 2
  • 3
  • 4
curl -i -X GET https://localhost:8080/items/quality/0

Example with quality 0

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:31:31 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T14:24:57.554567174
Content-Length: 221

[{"id":"c9","name":"Skatole","type":"Passive","statistics":[],"description":"Fly Love","itemPools":["ShellGame"],"quality":0,"gameVersions":["Flash"],"note":"A lot of fly enemies are no longer aggressive towards Isaac."}]

Query an Item

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/item/c1

Example with item id c1

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:42:52 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T14:37:15.959667568
Content-Length: 233

{"id":"c1","name":"The Sad Onion","type":"Passive","statistics":[{"type":"Tears","value":"+0.7","gameVersions":null}],"description":"Tears Up","itemPools":["TreasureRoom","CraneGame"],"quality":3,"gameVersions":["Flash"],"note":null}

Query a Random Item

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/items/d6
  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:44:49 GMT
Content-Type: application/json
Content-Length: 696

{"id":"c2","name":"The Inner Eye","type":"Passive","statistics":[{"type":"Tears","value":"-49%","gameVersions":null},{"type":"TearAmount","value":"x3","gameVersions":null}],"description":"Triple shot","itemPools":["TreasureRoom"],"quality":2,"gameVersions":["Flash"],"note":null}

Random item obtained is The Inner Eye


Query a Random Item by Pool

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/items/d6/pool/TreasureRoom

Example with TreasureRoom Pool

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:48:56 GMT
Content-Type: application/json
Content-Length: 284

{"id":"c8","name":"Brother Bobby","type":"Passive","statistics":[],"description":"Friends 'till the end","itemPools":["BabyShop","DevilRoom","TreasureRoom"],"quality":1,"gameVersions":["Flash"],"note":"Spawns a familiar that follows Isaac around shooting tears that deal 3.5 damage."}

Random item obtained is Brother Bobby


Query a Random Item by Quality

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/items/d6/quality/1

Example with Quality 1

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 13:59:06 GMT
Content-Type: application/json
Content-Length: 387

{"id":"c222 ","name":"Anti-Gravity","type":"Passive","statistics":[{"type":"TearRate","value":"+1","gameVersions":null}],"description":"Anti-gravity tears + tears up","itemPools":["TreasureRoom"],"quality":1,"gameVersions":["Rebirth"],"note":"Holding the fire buttons causes tears to hover in midair. When released, the tears will all shoot in the direction they were originally fired."}

Random item obtained is Anti-Gravity


Query a Spindown Item

A spindown item is the item having the id juste under the one specified

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/item/spindown/c2

Example with item c2

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 14:06:14 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T15:06:14.850641989
Content-Length: 233

{"id":"c1","name":"The Sad Onion","type":"Passive","statistics":[{"type":"Tears","value":"+0.7","gameVersions":null}],"description":"Tears Up","itemPools":["TreasureRoom","CraneGame"],"quality":3,"gameVersions":["Flash"],"note":null}

Spindown item obtained is The Sad Onion with the id c1


Create a new Item

id should be of this form cX replace X by the number of the item

Available type
  • Active
  • Card
  • Passive
  • Pill
  • Trinket
Available itemPools
  • AngelRoom
  • BabyShop
  • BatteryBum
  • Beggar
  • BombBum
  • Boss
  • CraneGame
  • CurseRoom
  • DevilBeggar
  • DevilRoom
  • GoldenChest
  • KeyMaster
  • Library
  • MomsChest
  • OldChest
  • Planetarium
  • RedChest
  • RottenBeggar
  • SecretRoom
  • ShellGame
  • Shop
  • TreasureRoom
  • UltraSecretRoom
  • WoodenChest
Available Qualities
  • 0
  • 1
  • 2
  • 3
  • 4
Available Statistics Type
  • Damage
  • Speed
  • Tears
  • Attack
  • Range
  • ShotSpeed
  • Luck
  • Size
  • DevilDealChance
  • AngelDealChance
  • PlanetariumChance
  • Health
  • TearAmount
  • TearEffect
  • TearRate
  • TearSize
Available GameVersion
  • Flash
  • Rebirth
  • Afterbirth
  • AfterbirthPlus
  • Repentance
  • RepentancePlus
  • All
  • Command:
curl -i -X POST \
     -H "Content-Type: application/json" \
     -d '{"id":"c90","name":"The Small Rock","type":"Passive","itemPools":["CraneGame"],"statistics":[{"type":"Damage","value": "+1"},{"type":"Speed","value": "-0.2"},{"type":"Tears","value": "+0.2"}],"description": "DMG up + speed down","quality":3,"gameVersions":["Rebirth"],"note": "Has a chance to drop when exploding a tinted rock"}' \
      https://tboi.dl-dai-heig.duckdns.org/items

Example create the new item The Small Rock

  • Result:
HTTP/1.1 201 Created
Date: Fri, 17 Jan 2025 14:36:02 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T15:36:02.111718491
Content-Length: 366

{"id":"c90","name":"The Small Rock","type":"Passive","statistics":[{"type":"Damage","value":"+1","gameVersions":null},{"type":"Speed","value":"-0.2","gameVersions":null},{"type":"Tears","value":"+0.2","gameVersions":null}],"description":null,"itemPools":["CraneGame"],"quality":3,"gameVersions":["Rebirth"],"note":"Has a chance to drop when exploding a tinted rock"}

Update an Item

  • Command:
curl -i -X PATCH \
     -H "Content-Type: application/json" \
     -d '{"name":"The Small Rocks","type":"Passive","itemPools":["CraneGame"],"statistics":[{"type":"Damage","value": "+1"},{"type":"Speed","value": "-0.2"},{"type":"Tears","value": "+0.2"}],"description": "DMG up + speed down","quality":3,"gameVersions":["Rebirth"],"note": "Has a chance to drop when exploding a tinted rock"}' \
      https://tboi.dl-dai-heig.duckdns.org/item/c90

Example update the new item The Small Rock change its name to The Small Rocks

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 14:44:31 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T15:44:31.467168856
Content-Length: 367

{"id":"c90","name":"The Small Rocks","type":"Passive","statistics":[{"type":"Damage","value":"+1","gameVersions":null},{"type":"Speed","value":"-0.2","gameVersions":null},{"type":"Tears","value":"+0.2","gameVersions":null}],"description":null,"itemPools":["CraneGame"],"quality":3,"gameVersions":["Rebirth"],"note":"Has a chance to drop when exploding a tinted rock"}

Delete an Item

  • Command:
curl -i -X DELETE https://tboi.dl-dai-heig.duckdns.org/item/c90

Example delete the added item The Small Rock

  • Result:
HTTP/1.1 204 No Content
Date: Fri, 17 Jan 2025 15:04:00 GMT
Content-Type: text/plain

Query All Characters

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/characters
  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 17:41:02 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T18:40:59.993261487
Content-Length: 167

[{"id":"1","name":"Isaac","hearts":"3 red hearts","damage":3.5,"shotSpeed":1.0,"range":6.5,"speed":1.0,"luck":1.0,"startingPickups":"1 bomb","startingItems":"The D6"}]

Query a Character

  • Command:
curl -i -X GET https://tboi.dl-dai-heig.duckdns.org/character/1

Example query the character with the id 1

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 17:43:28 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T18:43:28.328415099
Content-Length: 165

{"id":"1","name":"Isaac","hearts":"3 red hearts","damage":3.5,"shotSpeed":1.0,"range":6.5,"speed":1.0,"luck":1.0,"startingPickups":"1 bomb","startingItems":"The D6"}

Create a Character

id should be a number, all the other fields are Strings, there are no predefined types

  • Command:
curl -i -X POST \
     -H "Content-Type: application/json" \
     -d '{"id":"2","name":"Azazel","hearts":"3 black hearts","damage":5.25,"shotSpeed":1.0,"range":4.5,"speed":1.25,"luck":0.0,"startingPickups":"0 - The Fool","startingItems":"Short range Brimstone"}' \
     https://tboi.dl-dai-heig.duckdns.org/characters

Example create the character Azazel

  • Result:
HTTP/1.1 201 Created
Date: Fri, 17 Jan 2025 17:57:26 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T18:57:27.046896609
Content-Length: 191

{"id":"2","name":"Azazel","hearts":"3 black hearts","damage":5.25,"shotSpeed":1.0,"range":4.5,"speed":1.25,"luck":0.0,"startingPickups":"0 - The Fool","startingItems":"Short range Brimstone"}

Update a Character

  • Command:
curl -i -X PATCH \
     -H "Content-Type: application/json" \
     -d '{"id":"2","name":"Azazel","hearts":"4 black hearts","damage":5.25,"shotSpeed":1.0,"range":4.5,"speed":1.25,"luck":0.0,"startingPickups":"0 - The Fool","startingItems":"Short range Brimstone"}' \
     https://tboi.dl-dai-heig.duckdns.org/character/2

Example update the added character Azazel change 3 hearts to 4 hearts

  • Result:
HTTP/1.1 200 OK
Date: Fri, 17 Jan 2025 18:01:00 GMT
Content-Type: application/json
Last-Modified: 2025-01-17T19:01:00.584206
Content-Length: 191

{"id":"2","name":"Azazel","hearts":"4 black hearts","damage":5.25,"shotSpeed":1.0,"range":4.5,"speed":1.25,"luck":0.0,"startingPickups":"0 - The Fool","startingItems":"Short range Brimstone"}

Delete a Character

  • Command:
curl -i -X DELETE https://tboi.dl-dai-heig.duckdns.org/character/2

Example delete the added character Azazel

  • Result:
HTTP/1.1 204 No Content
Date: Fri, 17 Jan 2025 18:02:01 GMT
Content-Type: text/plain

Web infrastructures

Set up the virtual machine

Note

Some elements in the following section assume you already have some knowledge about SSH and how to do an extremely basic setup of a virtual machine (VPS)

Once you have a virtual machine, turned it on and connected to it using your favorite ssh client (either using username/password or an SSH key), do the following commands

sudo apt update -y && sudo apt upgrade -y

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

# Install Git
sudo add-apt-repository ppa:git-core/ppa
sudo apt update -y
sudo apt install git -y

DNS

Note

You can use your favorite Domain Name provider. We recommend DuckDNS as it is free

You can log-in using your GitHub account, and get 5 free domains. Here is an example on how to set it up

You add the domain name you want atop, click Add Domain, then edit the Current IP field to match the one of your virtual machine, which you can find on its dashboard

Deploy

Once you have set the domain name up, and started the application as well as Traefik, as mentioned in the "How to run the API" section, you should be able to access the API from your favorite browser at the domain you set up earlier.

Domain names

nslookup dl-dai-heig.duckdns.org
Server:         10.255.255.254
Address:        10.255.255.254#53

Non-authoritative answer:
Name:   dl-dai-heig.duckdns.org
Address: 20.61.77.88

img