apimastery / APISimulator

API Simulator - configuration-driven tool for modeling and running of API simulations
https://apisimulator.io
3 stars 1 forks source link

Reload simulations #3

Closed x80486 closed 3 years ago

x80486 commented 3 years ago

The way API Simulator loads the simulations is pretty handy, but once they are loaded and more changes are needed on a given (set of) simulation(s), it needs to be restarted to be able to pick up the changes.

It would be great if there is an end-point, e.g.: __admin/simulations/reload, that can be POSTed to reload/reset all the changes without stopping API Simulator.

As a bonus, it would be also nice to get all the defined simulations, e.g.: __admin/simulations.

apisim commented 3 years ago

Hi @x80486

Yes, you are right. In fact, that is one of the features we are working on right now! There are some enhancements that have to be made first to the underlying configuration library to support updates (adding simlets at run-time already works and the Embedded API Simulator uses that).

Most likely the admin server "inside" API Simulator that runs on a separate port will expose enpoint(s) for this instead of having endpoint(s) on the same port number as for the simulation requests...but that is still TBD.

Thanks! Keep the suggestions coming :-)

apisim commented 3 years ago

Implemented and released with v1.8.

Feedback is welcome!

x80486 commented 3 years ago

All right! Thank you so much! I'll test this one before the end of the week!

x80486 commented 3 years ago

This one looks like it doesn't work. This is what I'm doing:

...but I can't see the change, nor I can see anything in this section to refresh/reload the simulations.

Is there any other place I should be looking for this one? I always missed the section in the documentation :innocent:


For listing the simulations I was trying this:

$ curl --location --request GET http://localhost:6190/api/v1/apisims/create-character/simlets --header "Accept: application/json" --header "APISIMULATOR-API-KEY: apisimulator"
curl: (7) Failed to connect to localhost port 6190: Connection refused
apisim commented 3 years ago

Hi @x80486,

I'm sorry if there's a misunderstanding. The Create Simlets API operation expects new or updated simlet definition(s) to be submitted in the body of a POST request. This way, one can use the API to make changes to a simulation without restarting the API Simulator.


Could you check when running API Simulator in a Docker container (using the 1.8 image) and want to access the Admin API that the container port 6190 for the Admin Server is mapped as well? For example: ...-p 6090:6090 -p 6190:6190...

x80486 commented 3 years ago

You were right, I missed the port binding for the Admin Server. That's working fine now.

So if I have a simlet.yaml with something like this:

simlet: retrieve-character

# ...parameters
character:
  is: parameter
  from: csv
  file: "${simlets.path}/characters-api/characters.csv"
  keys:
    - character_id

...

...and I do:

$ curl --location --request GET http://localhost:6190/api/v1/apisims/retrieve-character/simlets \
    --header "Accept: application/json" \
    --header "APISIMULATOR-API-KEY: apisimulator"

Shouldn't that be OK to send back the simulations for the same? I'm getting this:

{
  "errors": [
    {
      "msg": "Simulation 'retrieve-character' not found in this API Simulator"
    }
  ]
}

I know that simulation config loads fine, because I can hit the actual endpoint(s) and retrieve the expected data/response(s).

x80486 commented 3 years ago

On the other hand, and more related to this issue, I think it would be really helpful to have a ../reload endpoint (or something around those lines). I'm borrowing that from WireMock — they have such endpoint that when you hit it, everything gets reset and what's in the filesystem gets reloaded, similar to when it's starting for the first time, hence the entire configuration is new (and updated, if anything).

Probably that would be effectively the same as doing DELETE /api/v1/apisims/{simName}/simlets and POSTing all simlets one by one, but automated — and preferably including also helper files that simulations use.

apisim commented 3 years ago

Hi @x80486

Glad to hear that the v1.8 Docker image is working for you. :+1:

In regards to '..."Simulation 'retrieve-character' not found in this API Simulator"': The URI pattern is /api/v1/apisims/{simName}/simlets, so in /api/v1/apisims/retrieve-character/simlets, "retrieve-character" is expected to be the simulation name ({simName}) whereas it is the name of a simlet.

Passing in the simulation name (which is the name of the directory) in the GET request should give you the list of the simlets...

I know it might be confusing right now because currently in an API Simulator there's only one simulation but we wanted to have the Admin API be ready for a time when an API Simulator will house more than one simulation.


Probably that would be effectively the same as doing DELETE /api/v1/apisims/{simName}/simlets and POSTing all simlets one by one, but automated — and preferably including also helper files that simulations use.

Got it, and agree. The first release of the Admin APIs, as the documentation states, doesn't support uploading external files. So, if external files are being used, it wouldn't be exactly the same as to remove all simlets and then re-create them with the API.

I'd suggest we keep this issue open. It was already prioritized internally and will be implemented. The thought right now is that the API call to re-load/refresh the simulation configuration and its simlets from source (the file system) will be something among the lines of

PATCH /api/v1/apisims/{simName}

Many thanks, @x80486 , for the feedback and the suggestions!

x80486 commented 3 years ago

All right, I'll leave it open then!

Going back to the Listing Simulations issue, I have a small project with this structure:

.
├── README.asciidoc
├── docker-compose.yml
└── simulations
    ├── response-not-found.json
    └── simlets
        └── characters-api
            ├── characters.csv
            ├── create-character
            │   └── simlet.yaml
            └── retrieve-character
                ├── character.response.json
                └── simlet.yaml

I do mount simulations/ while using Docker: "./simulations:/home/apisimulator/simulations". With that structure, I've tried characters-api, create-character, and retrieve-character...all return the same response (with different simulation name):

{
  "errors": [
    {
      "msg": "Simulation 'retrieve-character' not found in this API Simulator"
    }
  ]
}

Notice that the directory name is effectively the same as the simlet names/identifiers for create-character and retrieve-character. characters-api is just an umbrella directory to organize anything-character.


By the way, thanks for the changes/improvements, @apisim ...and happy new year! :partying_face: :balloon:

apisim commented 3 years ago

Including the project's structure and the details of how the volume is mounted in the Docker container helps.

Based on that, I'd guess that API Simulator is started with something like

docker run .... apisimulator start /home/apisimulator/simulations

The name of the simulation is the name of the directory - simulations in this case. The API call then to list its simlets will be:

GET /api/v1/apisims/simulations/simlets

Perhaps some explanation is warranted... An API Simulation consists of simlets. In this project, create-character and retrieve-character are the simlets.

We've seen people going a level (or even more!) deeper under the "simlets" directory when there's a larger number of simlets in a simulation and they want to organize them in some logical way (that makes sense for the simulation). Either way, it works because of the simlet auto-discovery mechanism API Simulator uses when looking under the "simlets" directory.

If we were to slightly reorganize the project:

.
├── README.asciidoc
├── docker-compose.yml
└── characters-api
    ├── response-not-found.json
    └── simlets
        ├── characters.csv
        ├── create-character
        │   └── simlet.yaml
        └── retrieve-character
            ├── character.response.json
            └── simlet.yaml

...the name of the simulation will become characters-api, ...the volume mount -v ./characters-api:/home/apisimulator/characters-api, for example, if we were to keep the directory names, ...and retrieving the list of it simlets:

GET /api/v1/apisims/characters-api/simlets

 

Happy New Year, @x80486 !

apisim commented 3 years ago

Hi @x80486

API Simulator v1.9 is out and it adds Reload Simulation and Get a Simlet APIs. When you get a chance...we'd appreciate if you could try it out and let us know what you think...

I know it's been a while - have been mostly busy with API Simulator Cloud :fire:

Thanks!

x80486 commented 3 years ago

Hello @apisim! Thanks for the heads-up; I'll upgrade the containers that I have running API Simulator and test those two new features! 🥳

Will let you know!

x80486 commented 3 years ago

Both features work flawlessly! Very useful the reload simulation one!

Waiting for the cloud service to see how it looks like when logged in! 🥳