Enable arbitrary changes to data buckets
It'd be great to have a way to apply custom logic to make arbitrary changes to a data bucket. For example, this would allow to do things like increment a value, or set values based on the provided request parameters. I know that the CRUD routes already allow modifying data, but the changes are (obviously) strictly limited to CRUD functions. Being able to apply custom logic would allow to make any arbitrary changes on via arbitrary routes.
I understand this is at the edge of what a mock server should do. But still, even basic scripting capabilities would be great to have in some cases.
+1 for this, seems like a very neat idea and would allow ability to create semi-stateful mocks across multiple requests and have a way to "refresh the cache" after a journey has been walked through or made.
+1 for this. I am trying to mock API with tasks. POST to create a task and multiple sequential GET to retrieve a task state. I don't need CRUD. Custom template helpers could work. Something like "setVar" but "setData". A helper to retrieve data from the bucket already exists.
Gave this a little thought. Imagine a scenario where you've got Mockoon running with multiple replicas on kubernetes or docker. Now by introducing a state in the actual service, you can very easily run into state mismatches between the different replicas.
Let's imagine we have a deployment which contains 3 replicas of Mockoon service. Each of these replicas has its own databucket state that can now be controlled or arbitrarily edited. When I make my first request, the default behavior of most load balancers is to round-robin the requests to all of the replicas one at a time.
Request #1 - goes to replica #1 which sets up some state.
Request #2 - gets round robined to replica #2 which now has a state mismatch between the replicas.
This could be resolved using sticky sessions, but not the solution for scalability and resiliency.
I'd suggest having some plug and play interconnectivity with some centralized caching/db solution such as redis to hold KV pairs or states in such cases instead of in-memory cache.
@martin-bucinskas I believe it's really advance scenario. And Mockoon already has the problem that you have described. The "Request number" rule for responses won't work correctly in your scenario.
It would be great to have such feature as state for multiple instances, no doubt, but it seems like overcomplicating for now. IMHO
Just of curiosity, why do you need to run multiple instances of Mockoon?
@martin-bucinskas I believe it's really advance scenario. And Mockoon already has the problem that you have described. The "Request number" rule for responses won't work correctly in your scenario.
It would be great to have such feature as state for multiple instances, no doubt, but it seems like overcomplicating for now. IMHO
Just of curiosity, why do you need to run multiple instances of Mockoon?
Ah, great point about the request numbers, I haven't had a time to use or take a look at that. I still think it may be a good add-on on top or a little extension, I sort of imagine something from DAPR playbook, how they have adaptable interfaces for components, creates a very flexible and easy to navigate architecture.
I know some people and companies use Mockoon to showcase the user journeys, running multiple instances of applications and apis is a must in terms of scalability and resiliency where you have a commitment to provide to your own clients or users.
+1 for me too! In particular, this feature would allow us to bypass the authentication and authorization server and simulate different users without having to use different services but having just everything inside Mockoon. At the moment we have this workflow for our client side applications:
- user starts the application (clientUrl:port/appname)
- the application checks if the user is authenticated 2.a if not a request to the authentication server is done and after the login returns to a specific page of the client (authServer -> clientUrl:port/appname/home)
- if yes, it loads some user information (backendUrl:port/apis/user)
If the user could do it, the system allows to impersonate someone (useful for checking what the other user could do). This is performed with a post to an url (backendUrl:port/apis/changeUser). From now every other request to backendUrl:port/apis/user returns the information of the impersonated user, not the original one. To exit from this situation another post to a different url is required (backendUrl:port/apis/changeUser/exit).
Up to now I can mock all the process in the first 3 steps using Mockoon and ready answers. It works great, it allows me to avoid the login and develop faster the application. What is not working is the request to change the user. I could mock it of course, but I always get the original content. I could also modify this content, but this needs to interact with Mockoon, hence it is not working on a test server.
With the opportunity to modify the mock without having to use CRUD urls I could change the content of it (I could also simulate different users with different rules), and restore the original state on the exit.
I'm not sure to get precisely what you are all trying to achieve. It seems that some of you have very specific use cases 🙂
After thinking about it for a while, and also about this other issue I'm not sure if 2 systems should coexist, or if the data buckets could do both. My feeling right now is that the data buckets were created to be a JSON DB like system, coupled to CRUD operations. More or less a replacement for json-server. It's already possible to store arbitrary data in a bucket using a CRUD's POST call as buckets can store strings, booleans, etc. It's even possible to use information from a request as the bucket's generation will be delayed to the first request. But I have the impression that trying to modying the bucket outside of CRUD endpoints, by using templating helpers as it was suggested, could be confusing.
After all, the buckets behavior is a bit specific and what @jphalip describes sounds more like what is discussed here. Maybe a system of key/value store that is not "static" like the buckets but re-evaluated during every HTTP transaction would be better. It could also allow for behavior that are not dictated by the request (increment, decrement, etc.), and would be a good candidate for a templating helper like setGlobalVar.
Using existing templating helpers it would be "easy":
myVar1 {{ body 'prop1' }}
myVar2 {{ add (getGlobalVar 'myVar1') 1 }}
I would be interested to know what you think.
@255kb
Maybe a system of key/value store that is not "static" like the buckets but re-evaluated during every HTTP transaction would be better. It could also allow for behavior that are not dictated by the request (increment, decrement, etc.), and would be a good candidate for a templating helper like setGlobalVar. Using existing templating helpers it would be "easy":
myVar1 {{ body 'prop1' }}
myVar2 {{ add (getGlobalVar 'myVar1') 1 }}
I would be interested to know what you think.
I've read both the discussions and I can say that for my specific case this solution fits exactly. Not only, it would make even simpler the 'handling', because I would have just a single change, the global var, and not a complicated update of the bucket. Re-reading my sample, and comparing with the other request, now I see that the change in the data bucket would be a forceful one. Hence, if global variables would exists and would be accessible from every route (GET/POST...), my flow would be:
- user login (set of the default value for the global var - maybe a reference to a bucket where several users are stored)
- data filtered according to the current user (got from the global var)
- current user impersonates another user (the new value overwrites the original one)
- data filtered according to the current user (got from the global var), but this time the value is a different one
- user ends to impersonate someone else (the global var get the value stored into a backup var)
This would completely solve my use case in a way that, maybe, even the custom change in the data bucket would not have done.
The global variables were released in December. I suggest that you have a look to see if it could solve your use cases, or if we would still need some other mechanism involving the data buckets.
Hi!
So, before I was on holidays, then really busy at work (not a nice start of the year...). I had just yesterday time to try this new feature.
My response is: it works great! Thank you very much. It does exactly what I need.
Best regards and thanks again for the great work you are doing. I really enjoy using Mockoon.
Ciao, Luca
Il giorno mer 3 gen 2024 alle ore 08:59 Guillaume @.***> ha scritto:
The global variables https://mockoon.com/docs/latest/global-variables/overview/ were released in December. I suggest that you have a look to see if it could solve your use cases, or if we would still need some other mechanism involving the data buckets.
— Reply to this email directly, view it on GitHub https://github.com/mockoon/mockoon/issues/1098#issuecomment-1874973853, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEXPQCC6U6SEDCNPKPJRA73YMUFW3AVCNFSM6AAAAAA24WTISWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZUHE3TGOBVGM . You are receiving this because you commented.Message ID: @.***>
Hi! So, before I was on holidays, then really busy at work (not a nice start of the year...). I had just yesterday time to try this new feature. My response is: it works great! Thank you very much. It does exactly what I need. Best regards and thanks again for the great work you are doing. I really enjoy using Mockoon.
You're welcome! I'm glad you like it 🤗
Will close this for now, as most of the use cases seem to be handled by the global variables.