Comments (18)
First, this is a sweet resource. I have just stumbled upon it.
It would be great if the endpoints can be mapped via a configuration file, rather than chaining a bunch of .get
, .post
, etc methods to the new class (or .add
this, .add
thats).
Take an API such as TMDB with scores of endpoints, and it can get out of hand and hard to read. There are a couple of javascript TMDB repos that handle this via an endpoints.js
file that they use to generate the actual API routes from. See impronunciable/moviedb and grantholle/moviedb-promise.
Having a config file would allow one to easily swap out API's, let's say I want to use TRAKT for media info. I can create another endpoint file and keep the same action
names within vuex, just using a different API to get the data.
from vuex-rest-api.
What about a global onError
interceptor that can be overridden at the resource entity level?
I imagine this might be tricky to achieve given module namespacing in vuex
, but I think it would be very useful - that way you don't have to write/import the same onError
snippet in every single resource entity.
from vuex-rest-api.
I love the library, it has a clean interface and does an excellent job!
What do you think about supporting custom pre-flight validation methods on the non-idempotent HTTP methods (e.g. POST
, PUT
, PATCH
)? Requests would only be sent out over the network if the provided request body passes the user's validation function, otherwise a custom error callback could be invoked.
One use case would be allowing easy integration with tools like JSON Schema. Users could just provide a callback that passes the desired request body and a JSON Schema corresponding with the API resource into a validation module such as ajv
or is-my-json-valid
.
from vuex-rest-api.
Hello @slurmulon ,
custom pre-flight validation methods sound indeed useful and the integration with JSON Schema is also a neat idea I've never thought about. Thanks for your contribution and the compliment!
At the moment I'm waiting for changes on Vuex. Seems like there will be several big changes in the next major release.
from vuex-rest-api.
@someone1 This sounds good to me at first glance. But I think this will exceed the scope of vuex-rest-api because:
- I don't wanna maintain a CLI for this tool, also it would create an additional cognitive barrier (should I use the CLI or do it programmatically?)
- If I add an CLI there will be questions why other commands are not avaible through it and so on
- vuex-rest-api can be used with multiple stores. So how should I create an spec file in this case?
- this tool is already too complicated in some aspects. I want to simplify it. IMHO a CLI would have the opposite effect.
from vuex-rest-api.
@slurmulon Seems reasonable. I've added it to the list!
from vuex-rest-api.
Here's my idea to new syntax with some new functions I miss on current version with examples how they could be used:
.actions({
getPost: {
method: 'GET',
path: ({ id }) => '/post/${id}',
property: 'post'
},
getPosts: {
pluralOf: 'getPost'
}
})
.common({
onSuccess: (actionConfig) => (state, payload, axios) => {
const { data, metadata } = payload.data
state[actionConfig.property] = data
if (metadata) {
state[actionConfig.property + 'Metadata'] = metadata
}
},
retry: {
delays: (attempt) => Math.pow(2, attempt + 4) * 100,
timeout: 15000,
statusCodes: (statusCode) => statusCode >= 500,
beforeRetry: ({ forceRetry, abort, delay, attempt, lastError, req }) => {
if (attempt > 10) {
abort()
}
window.forceRetry = forceRetry
},
}
})
- .actions() method to define actions
- Defining by action names in same object would prevent duplicates in action names and users could easily create some helpers to build their config from some array of endpoints definitions (e.g.:
const actions = endpoints.reduce((acc, item) => ({ ...acc, [item.method + item.entityName]: { /* ... */ } }), {})
) - method prop would define method type, which is pretty boring, but it would be cool if it could automatically get method type from action's name if not defined by user (actionName.startsWith('get') = GET, startsWith('update') = PUT, ...)
- Plural helper would automatically create plural action of other action, which means it would just copy path without params and property of that action and add 's' to the end of both. e.g.: if action
getPosts
has settingpluralOf: 'getPost'
it would setpath: '/posts', property: 'posts'
togetPosts
action. Of course the problem here is how to deal with id or other path params. - .common() method to define common properties for all actions in a module (or also in all modules somehow). Functions defined in common method would be wrapped in another function that will provide config of an action, that triggered this function. e.g. action
getPost
triggeredonSuccess
, that is defined as common, vuex-rest-api would call something likecommon.onSuccess(actions.getPost)(state, payload, axios, actionParams)
- retry property is inspired by fantastic retryMiddleware from react-relay-network-modern. It would help user to retry request if error occured. Also it would probably be useful to send
retry
function as argument toonError
callback
delays
: number, array of numbers or function that receives number of attempt as argument to calculate delay between retry requests
timeout
: number that represent max wait time for response
statusCodes
: array of numbers or function defining which response status codes will trigger retry
beforeRetry
: function called before retry attempt, enabling user to stop another retry attempts or edit retry request before sending
from vuex-rest-api.
@christianmalek,
If I was to work within current vuex-rest-api to cancel a request manually, I would be overriding the onSuccess and having a token (similar to described in the SO answer) that would tell me at that point if I needed to commit the response, or ignore it because I have a newer one pending. It would basically be a wrapper around vuex-rest-api to handle the cancellation process.
I am not 100% sure if that was the question you were asking - if not, let me know! Thanks.
from vuex-rest-api.
@webstractions This seems also plausible to me. I've added it on the list of features for v3 (see #57). Thanks for your contribution!
from vuex-rest-api.
@christianmalek I am working on something right now using this repo. Chances are, I will be writing a function to import the endpoint mapping and generate the gets, posts, etc via an .add
loop of some sort. If you want, I can fork this and submit a PR for you.
from vuex-rest-api.
@webstractions PRs are always welcome. Please note that the base of this utility is written in TypeScript. So I will only accept PRs in TypeScript.
from vuex-rest-api.
@christianmalek Yikes. I just noticed that. Looks like I need to pick up a book and do a little brushing up.
from vuex-rest-api.
Maybe a CLI tool for parsing a swagger/OpenAPI spec file to an (typescript) output leveraging vuex-rest-api? Or a load function that takes a swagger spec and spits out a Vapi object?
Not sure how, if at all, this fits into this project. I can already generate a typescript client using swagger-codegen which does a LOT of the work for me, but I can't plug that into vuex without the manual boilerplate. This project would alleviate that but basically recreates the API client for me, but I can't generate the client.
from vuex-rest-api.
What do you guys think about an alternative syntax of adding the actions?
Here are some ideas:
.get({
action: "getPost",
property: "post",
path: ({ id }) => `/posts/${id}`,
// additional params...
})
.get("getPost", "post", ({ id }) => `/posts/${id}`, {
// additional params...
})
.add("GET posts/:id INTO post AS getPost", {
// additional params...
})
.get("posts/:id INTO post AS getPost", {
// additional params
})
from vuex-rest-api.
@christianmalek I think that the configuration object approach is still the best.
For what it's worth, here's my thinking (skipping over the last idea since it's so similar to the idea before it):
Idea 1
.get("getPost", "post", ({ id }) => `/posts/${id}`, {
// additional params...
})
This approach is regressing back to ES5 days where we didn't have parameter destructuring and therefore it misses out on the benefits.
The primary downside is that the user has to remember the ordering of the parameters. It also makes omitting arguments awkward (e.g. you have to use null
to skip over an unneeded param).
Idea 2
.add("GET posts/:id INTO post AS getPost", {
// additional params...
})
To me the parameters in this context are so straight forward that they don't justify creating a special syntax.
It also loses out on the benefits of having path
as a Function
, so in certain situations you will end up having to use some config object anyways.
For example, what if id
is a nested property? The only way I can see it working is by adding some extra params
configuration with a callback or by using something like JSON Pointer (like what JSON Hyper-Schema does)
.add("GET posts/:id INTO post AS getPost", {
params: {
id: entity => entity.data.id // or `'#/data/id'`
}
})
You could also inline JSON Pointer, but at that point it's getting kind of complicated and still isn't as powerful (or pretty) as a simple callback:
.add("GET posts/{#/data/id} INTO post AS getPost")
In general it feels strange that some functionality is covered by this specially formatted String
but other functionality is not.
I think an idiomatic and homogeneous solution (like what exists today) is simply more intuitive and less complex than what's being proposed.
from vuex-rest-api.
@BorisTB Thanks. These are some awesome ideas. Thanks for your input!
ad 1: I'm with you.
ad 2: Awesome idea. The only downside would be the API incompatibility.
ad 3: Here I'm also with you. I would say that raising an exception in case of unknown action commands (get, post, put) would be a good addition to this (in favor of just defaulting to eg GET).
ad 4: The idea of an plural helper sounds nice. But I don't think this is the proper way. Maybe we should open another issue for this and discuss the pros and cons of different implementations.
ad 5: Something like this is planned. I think it would be clever to discuss pros and cons of this first before implementation.
ad 6: I like this. Do you know a good library for this?
from vuex-rest-api.
Some way to cancel a current request would be fantastic. In my use case, I have a web page that automatically refreshes the store every X seconds. You can also do a search or a filter and it will refresh. Sometimes, the search and the auto-refresh happen near the same time, and you will get a flash of your search and then it will be overwritten by the auto refresh, which was sent out first (before filters changed) but came back last, overwriting the filtered results. Then the next auto refresh will correctly have the filtered results... All in all, a very confusing user experience.
I looked into ways of cancelling a current request and found this: https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise#30235261
The proposal itself has died, but the token method does work. Perhaps there is a way to work this in?
A really awesome way to implement this would maybe be a property on a configuration that you can set to automatically cancel any older requests when you send out a new one, so we can ensure we always are applying only the latest request. Ability to override the setting per-dispatch for extra points.
from vuex-rest-api.
Hey @qskousen,
Thanks for your suggestions! What would be your preferred way to cancel requests if you had to do it manually?
I looked into ways of cancelling a current request and found this: https://stackoverflow.com/questions/30233302/promise-is-it-possible-to-force-cancel-a-promise#30235261
axios supports already the proposed cancellation technique: https://github.com/axios/axios#cancellation
But it's not built into vuex-rest-api yet. Noted for version 3.
A really awesome way to implement this would maybe be a property on a configuration that you can set to automatically cancel any older requests when you send out a new one, so we can ensure we always are applying only the latest request. Ability to override the setting per-dispatch for extra points.
Sounds good in my ears. I've noted it for version 3, too.
from vuex-rest-api.
Related Issues (20)
- What does pending really mean? Not sure if this is intended behavior. HOT 2
- V3 - Checklist HOT 2
- Handling rejected promises HOT 3
- Update axios peer dependency HOT 6
- Can't install HOT 5
- Not possible to create a pr HOT 3
- [QUESTION] - Pre API Call Transformation HOT 3
- How to use vuex-rest-api with nuxt.js auth-module HOT 15
- Caching requested data HOT 8
- Using webpack: vuex_rest_api__WEBPACK_IMPORTED_MODULE_0___default.a is not a constructor HOT 4
- Correct way to change state HOT 9
- provide action payload in onSuccess HOT 4
- Add support of mapping response object to typed model objects HOT 1
- Section "calling-the-actions" disapeared from the docs HOT 2
- Not an issue tip for CORS. [Tips] HOT 1
- Callback when rest call completes HOT 2
- Support for Fetch API HOT 4
- Add ability to add "namespaced" option for "getStore" HOT 4
- How to get rid of error&pending in setting a custom state? HOT 7
- Update peer dependency of axios HOT 3
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 vuex-rest-api.