/star-wars-api

Kotlin facade for SWAPI (The Star Wars API)

Primary LanguageKotlinApache License 2.0Apache-2.0

star-wars-api

A Kotlin facade for SWAPI (The Star Wars API).

Technologies

Important: the external technologies are prerequisites and must be previously installed at your host to run the application.

Running the application

Tests

docker compose -f compose-test.yml up
  • After running the tests, a code coverage report generated by JaCoCo will be available at directory ./app-data/star-wars-api/reports/jacoco/codeCoverageReport/ of the host. Open html/index.html in your browser to see the report. Also, a XML file is available (codeCoverageReport.xml), for automated code coverage tools.
    • If you prefer another base directory instead of /app-data, set the environment variable HOST_APP_DATA_DIR.

Application

docker compose up
  • Important: the first execution will be slow, as Docker (and Gradle) will need to download all the necessary dependencies to build the images.
  • The command above will trigger the execution of two containers: MongoDB and the application itself.
  • Application logs will be available at directory ./app-data/star-wars-api/log/ of the host.
    • If you prefer another base directory instead of /app-data, set the environment variable HOST_APP_DATA_DIR.

Endpoints

  • URL: http://localhost:8080

REST

  • POST /v1.0/planets - given an id, load a planet from swapi and persist it in the application.

    Request

    curl -i -s -X POST 'http://localhost:8080/v1.0/planets' -H 'Content-Type: application/json' -d '{ "id": 9 }'


    Response Body (HTTP 201)

    {
      "name": "Coruscant",
      "climate": "temperate",
      "terrain": "cityscape, mountains",
      "films": [
        {
          "title": "Return of the Jedi",
          "director": "Richard Marquand",
          "releaseDate": "1983-05-25"
        },
        {
          "title": "The Phantom Menace",
          "director": "George Lucas",
          "releaseDate": "1999-05-19"
        },
        {
          "title": "Attack of the Clones",
          "director": "George Lucas",
          "releaseDate": "2002-05-16"
        },
        {
          "title": "Revenge of the Sith",
          "director": "George Lucas",
          "releaseDate": "2005-05-19"
        }
      ]
    }


    Other responses: HTTP 400, HTTP 422


  • GET /v1.0/planets - list all planets saved in the application.

    Request

    curl -i -s -X GET 'http://localhost:8080/v1.0/planets'


    Response Body (HTTP 200)

      [
        {
          "id": 9,
          "name": "Coruscant",
          "climate": "temperate",
          "terrain": "cityscape, mountains",
          "films": [
            {
              "title": "Return of the Jedi",
              "director": "Richard Marquand",
              "releaseDate": "1983-05-25"
            },
            {
              "title": "The Phantom Menace",
              "director": "George Lucas",
              "releaseDate": "1999-05-19"
            },
            {
              "title": "Attack of the Clones",
              "director": "George Lucas",
              "releaseDate": "2002-05-16"
            },
            {
              "title": "Revenge of the Sith",
              "director": "George Lucas",
              "releaseDate": "2005-05-19"
            }
          ]
        }
      ]


    Other responses:


  • GET /v1.0/planets/?name={name} - find a planet by name.

    • query parameters:
      • required:
        • name: string
    Request

    curl -i -s -X GET 'http://localhost:8080/v1.0/planets/?name=Coruscant'


    Response Body (HTTP 200)

    {
      "id": 9,
      "name": "Coruscant",
      "climate": "temperate",
      "terrain": "cityscape, mountains",
      "films": [
        {
          "title": "Return of the Jedi",
          "director": "Richard Marquand",
          "releaseDate": "1983-05-25"
        },
        {
          "title": "The Phantom Menace",
          "director": "George Lucas",
          "releaseDate": "1999-05-19"
        },
        {
          "title": "Attack of the Clones",
          "director": "George Lucas",
          "releaseDate": "2002-05-16"
        },
        {
          "title": "Revenge of the Sith",
          "director": "George Lucas",
          "releaseDate": "2005-05-19"
        }
      ]
    }


    Other responses: HTTP 404


  • GET /v1.0/planets/{id} - find a planet by id.

    • path parameters:
      • required:
        • id: int
    Request

    curl -i -s -X GET 'http://localhost:8080/v1.0/planets/9'


    Response Body (HTTP 200)

    {
      "id": 9,
      "name": "Coruscant",
      "climate": "temperate",
      "terrain": "cityscape, mountains",
      "films": [
        {
          "title": "Return of the Jedi",
          "director": "Richard Marquand",
          "releaseDate": "1983-05-25"
        },
        {
          "title": "The Phantom Menace",
          "director": "George Lucas",
          "releaseDate": "1999-05-19"
        },
        {
          "title": "Attack of the Clones",
          "director": "George Lucas",
          "releaseDate": "2002-05-16"
        },
        {
          "title": "Revenge of the Sith",
          "director": "George Lucas",
          "releaseDate": "2005-05-19"
        }
      ]
    }


    Other responses: HTTP 400, HTTP 404


  • DELETE /v1.0/planets/{id} - delete a planet.

    • path parameters:
      • required:
        • id: int
    Request

    curl -i -s -X DELETE 'http://localhost:8080/v1.0/planets/9'


    Response Body (HTTP 204)


    Other responses: HTTP 400, HTTP 404


  • Postman

Further discussions

Disclaimers:

  • MongoDB credentials were stored as plain text at configuration files. Naturally, in a Production system, such credentials would not be disclosed (typically they would be configured in a Secrets Manager).
  • Through a Docker volume (in compose-mongo.yml), the state of MongoDB is maintained between executions.

Possible improvements:

  • Implement a retry logic for Fuel calls to swapi at HttpClient.
  • Document the endpoints with OpenAPI (in addition to README + Postman).
  • Fine-tune the exclusion rules of JaCoCo plugin in order to discard meaningless classes from code coverage report (e.g. configuration classes, DTOs, etc).
  • Use the reactive version of MongoRepository (instead of triggering new coroutine contexts at PlanetRepositoryImpl).