Comments (12)
Hi Michael!
Thanks for the kind words :)
You're right. @kiaking and I had some similar thoughts and I really think we should do that.
In my opinion we should bring the interface to the vuex-orm core with some kind of adapter pattern, which allows plugins to add adapters. Much like js-data does this.
I could imagine way more adapters then REST/JSON and GraphQL: Firebase, localstorage and more.
@kiaking What's on your mind about this topic?
PS: Should we move that issue into the core issue tracker due to the fact that this is a general topic for the vuex-orm ecosystem?
from plugin-graphql.
Thanks for the quick reply!
Maybe it can be packed in the separate VuexORM plugin as this yours one. It has some sense to have a VuexORM as such a lightweight model layer which serves only the logic of communicating with Vuex and representing the API to use in the component layer of Vue app. However adding this to the core VuexORM API with the option of LocalStorage by default (for the projects which do not need the communication with serverside) would have some sense too.
I think this issue in anyway is in high demand because to build any serious project needs this persistence layer which would implement the communication with any kind of backend. And I suggest to discuss some solution for the design of this implementation and start working of it as the part of VuexORM core or as the plugin.
from plugin-graphql.
Nice to hear. I will be some tough work to define a common API that is generic enough for all kinds of persistence implementations.
I think the base persistence layer without any implementation is very lightweight and it should go into the core to have a single source of truth for the API design and the overall handling and feeling of the library.
from plugin-graphql.
Agree with you, it is clearer to have an interface in the core lib and endpoint for each API as plugins.
So if it's possible please describe here a structure how you see this base API and i will try to start implementing REST API logic.
from plugin-graphql.
Hi guys! Yeah, I think it's a good idea to have single API interface at the core library, or at least as a separated repo. I think it can be in the core until it becomes cluttered. So +1 for moving this issue to the core's issue tracker.
And here is my belief thought on this. In term of user point of view, the interface of the API should be quite simple. I think most of them are already defined at this library, thanks to @phortx.
Maybe we could come up with 3 layers of API.
- Interact with Vuex only.
- Interact with Backend Only.
- Interact with Both.
CRUD | Vuex Only | Backend Only | Both |
---|---|---|---|
READ | find | fetch | get |
Create | insert | persist | add |
Update | update | push | edit |
Delete | delete | destroy | remove |
Of course, the naming is just an idea but it's a bit more flexible, and a user could use the library to handle generic API call without interacting with Vuex ORM too. Maybe it is enough to have deleteAndDestroy
kinda method though.
I think the only thing library author must do is to implement all of the above methods as a modules and make it able to call store.dispatch('entities/users/persist', { ... })
.
To be consistent with the argument passed to the library could be tough though. For example, if we were to create REST API library, where should we define the endpoint (URL) for each method and such.
from plugin-graphql.
I like the idea of the 3 layer API but I think we should keep the number of terms low, so we don't confuse the developers. Thus I'm for the deleteAndDestroy
variant instead of a new set of terms :)
The argument topic is a difficult one. Maybe it's not even possible to have a real adapter independed API because of some specifics 🤔
Maybe we should create some wiki document or something to specify the API together?
from plugin-graphql.
I like the idea of the 3 layer API but I think we should keep the number of terms low, so we don't confuse the developers. Thus I'm for the deleteAndDestroy variant instead of a new set of terms :)
Yeah you got the point. I think so too.
The argument topic is a difficult one. Maybe it's not even possible to have a real adapter independed API because of some specifics
Yeah... Since we have to use Vuex API, we have the limitation that we can't change the number of arguments too. Anyway, I'll organize the thought and move this issue to the Core!
from plugin-graphql.
Thank you very much, kia :)
from plugin-graphql.
So yes i think it would be the best start point - to write smth like a wiki or create an interface class.
What about 3 layer interface in my opinion it seems more complicated than it has to be.
In fact i don't see any need to use the backend only api (or if there is ever such a possibility i think it should be the matter of another lib). The logic of Vuex-only API can be easily combined with the logic of persistence layer. For example if u've set up the backend plugin (for example REST API) and call the all method - library can check the in-memory store if it has any data already downloaded and if it has not - make and API call to backend, populate the store with data and return it to the user (sure we need some method which can synchronise the state). Method find is quite similar - search the in-memory store for the id and if it has no luck - ask server to search this id in DB. Creation and Destruction of objects sure are a bit different, you may need separate methods for creating the object in store without persistence and you may want to delete the object just in memory, but again methods create and destroy from the persistence layer can do both tasks at once - delete data from store and from real db at once.
I think interface must be as seamless as possible, offering the most popular cases with the less of configuration and the use of additional methods but sure it must be flexible enough too.
In fact we can start thinking about this API from some real-world example with the backend API and some components which don't need the persistence. For example some ecommerce resource with tons of products. So first of all we need to load the full Category list (and then we can operate with it just in memory) then we like to download some popular products (we can't load all of them in memory), then we need the ability to load products by categories, apply filters and so on (true backend part). And finally we can have just-in-memory shopping cart, for example we don't need to persist its contents (true Vuex part without any backend API).
So as the frontend developer all I want here to call Category.all method at the start point which create automatic request to backend and populate my Category model with data. Then i want to use find or where method (probably order_by and some others too) of Product model to automatically search the cached data or sending requests to server. And finally I want to setup my ShoppingCart model not to use any backend at all thus all its methods will become Vuex only and won't try to exec any backend logic.
Sure I can agree with @phortx here that there is a possibility that not all of the adapters would fit this logic but we can choose this way as the starting point.
from plugin-graphql.
What about 3 layer interface in my opinion it seems more complicated than it has to be.
In fact i don't see any need to use the backend only api (or if there is ever such a possibility i think it should be the matter of another lib). The logic of Vuex-only API can be easily combined with the logic of persistence layer. For example if u've set up the backend plugin (for example REST API) and call the all method - library can check the in-memory store if it has any data already downloaded and if it has not - make and API call to backend, populate the store with data and return it to the user (sure we need some method which can synchronise the state).
Unfortunately this is not practicable because you will loose some reactivity with that. We had a similar discussion and we decided not to combine fetching from the server and retrieving from the store.
First this might seem complicated but the other way would produce more complication in the long term.
We can reroll this discussion, but I think the separation of persistence and vuex API is a good way to go and we've made good experience with that :)
Also think of this: How can a call to Category.all
know if the records in the store are really all records? There could be more on the server, we can't know. So a Catagory.all
would always send a request to the server, which can lead to huge traffic.
I think interface must be as seamless as possible, offering the most popular cases with the less of configuration and the use of additional methods but sure it must be flexible enough too.
I'm on your side. But when you start to work on such plugins you will get in some difficult situations soon. For example does the JSON/REST specification (which is inofficial btw) not specify if keys are camelCase, hyphen-case or snake_case. What is the default behavior? Do you want support all of them? I had and have similar issues with GraphQL. The works-out-of-the-box-with-everything philosophy doesn't work well in the reality. Pity. :(
from plugin-graphql.
Yes sure these are just thoughts and I'm not so much acquainted with Vuex at this point but I think finally that it's possible to implement somehow and maybe the ease of the final use of this lib can cost some bigger efforts at the point of it's developing. I've tried some other libs before i came to the Vuex-ORM, e.g. JSORM (which implements JSON API frontend) and i liked it's design, it was developed with inspiration of Rails's ActiveRecord (I came here from the Rails world too) and it's API looks quite simple and powerful, but that library isn't stable yet and I got lots of errors trying to use it in my app. In addition it has nothing with Vuex and I prefer using native technologies with the frontend i choose.
In fact it will have sense to analyze several similar libraries and get their best sides.
Also think of this: How can a call to Category.all know if the records in the store are really all records? There could be more on the server, we can't know. So a Catagory.all would always send a request to the server, which can lead to huge traffic.
For example it can be done with the ability of pagination and total_count field.
I'm on your side. But when you start to work on such plugins you will get in some difficult situations soon. For example does the JSON/REST specification (which is inofficial btw) not specify if keys are camelCase, hyphen-case or snake_case. What is the default behavior? Do you want support all of them? I had and have similar issues with GraphQL. The works-out-of-the-box-with-everything philosophy doesn't work well in the reality. Pity. :(
Sure it's impossible to provide all the possible ways of use at once. In fact it's even not necessary at the moment. The problem with case again can be customisable, we can set the default behaviour which is the most popular and add the way to change it by providing such an option somewhere in the configuration options of the current model or as the global scope option. I like very much the Rails principal of convention over configuration (don't know why it has not become popular in JS world) - to implement some common default behaviour out of the box giving the way to customise everything if you need (mainly it relates to the naming conventions sure but can be expand on these questions too)
We can reroll this discussion, but I think the separation of persistence and vuex API is a good way to go and we've made good experience with that :)
Thumbs up! Let's create the new discussion at the core issue tracker and maybe with the help of others come to some API design which would be possible to start with.
I've already loved the Vue world it seemed to me very efficient and with such a powerful and well-thought ORM library it could become almost perfect for any type of task.
from plugin-graphql.
OK, I've created the issue at the core! Let's continue over there 👍
vuex-orm/vuex-orm#200
from plugin-graphql.
Related Issues (20)
- Forcing upcase on model name in buildQuery overwites value set by adapter
- Error: No such model HOT 1
- Need to change the "typings" path to "dist/index.d.ts" HOT 2
- morphToMany not return related models HOT 2
- Custom query not working returning Couldn't find Type of name UserInput in the GraphQL Schema. HOT 3
- Where to get type definitions for 'fetch' in TypeScript?
- v1.0.0-rc.42 not published to NPM? HOT 1
- Trouble with fetch() in Nuxt app HOT 1
- How to handle models that have multiple words? HOT 2
- Better documentation about how to $persist() a record with Many-to-many relationships
- getInputTypeName() seems to be ignored HOT 1
- GraphQL Upload support
- persist ID as string shows NaN HOT 2
- toPrimaryKey broke ObjectId from MongoDB HOT 1
- BUG: .$push does not add variables to variable definitions on mutation HOT 1
- method .all() not returns pure literal object from database (store)
- "Connection mode" doc page unclear
- Type errors HOT 1
- State of Vue 3 support? HOT 1
- Slack invite link is dead HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from plugin-graphql.