teamleadercrm / react-hooks-api Goto Github PK
View Code? Open in Web Editor NEW🎣Teamleader API react hooks
🎣Teamleader API react hooks
This proposal is related to #13.
There's a working implementation of #13, but we never discussed non-conventional CRUD
endpoints like .report
or other future endpoints. How do we handle calculation endpoints like these? Where do they belong in the store?
This RFC served more as a write-up for myself and documentation. Scroll down to see the actual proposal.
Our store is a normalized entity store. This means entities are stored using a unique identifier. In our case: their UUID. What gets returned from f.e. projectItems.report
is:
{
"data": {
"billableAmount": {
"amount": 1644.65,
"currency": "EUR"
},
"result": {
"amount": -195.35,
"currency": "EUR"
},
"cost": {
"amount": 1840,
"currency": "EUR"
},
"quantity": 28,
"type": "tracked_time",
"unit": "hour",
"participant": {
"type": "user",
"id": "d2886235-61f8-4c77-8e6f-d55f4c91f501"
}
}
There's nothing here to really identify this calculation by. As it's "just" a calculation at that point in time. It's not stored in the database, it's not an entity.
So let's first find something to identify this calculation by. We could generate an ID based on the parameters passed in the request body:
In the case of projectItems.report
this is
milestone_id
group_by
(an enum)While I was writing this down, it dawned on me that we can just store the returned data inside our queries
state object. It makes sense, since we're already generating a "unique" id for each query. This makes sure we don't pollute our entity
store with calculation data.
Only try to store actual entities
inside the entities
state object. Makes a lot of sense right? Inside of useQuery
I'll be adding a check if the action
is of the type info
or list
. And every other action will result in the response being set inside the queries
object, under their respective query identifier.
The useQuery hook isn't fully typed yet.
Let's make sure we have an entity store first (#3)
This proposal will serve as documentation and a place to discuss how the implementation works. What do we return as the data
object, how is the data stored under the hood and how is sideloading handled?
Already partially implemented in #11.
Entities will be written to a redux store, normalized by id. This way it's easy to do lookups and we avoid duplicate data. This is generally considered a best practice.
Next to the entities
state, we also have a queries
state. This is also an object containing all the queries that have been requested. This is where we will store the id (or ids) relevant to the query.
Here's an example of what the state could look like:
{
entities: {
projects: {
'708c8008-3455-49a9-b66a-5222bcadb0cc': {
id: '708c8008-3455-49a9-b66a-5222bcadb0cc',
title: 'Test project'
},
'e6538393-aa7e-4ec2-870b-f75b3d85f706': {
id: 'e6538393-aa7e-4ec2-870b-f75b3d85f706',
title: 'Test project2'
}
}
}
queries: {
'{"domain":"projects","action":"list"}': {
loading: false,
ids: ['708c8008-3455-49a9-b66a-5222bcadb0cc', 'e6538393-aa7e-4ec2-870b-f75b3d85f706'],
meta: {
matches: 50
}
}
}
}
By using a normalized state for entities, we can make sure that there's a single source of truth. This can be especially important when updating data. When we provide a way to do update requests using a new hook (hint, hint, useMutation
), some existing state that can be shared between multiple queries will have to be updated.
See #12
To take advantage of sideloading, but retain our normalized entities state, we need to be able to combine the data when selecting it. This is implemented in the referenced PR above, but as @duivvv mentioned, being able to merge sideloaded data is something that is also needed in sdk-js.
As react-hooks-api
is mostly a wrapper around sdk-js
, it makes sense to create an exported plugin called merge
in the sdk-js repo that can be used to select and merge the included data. See RFC sdk-js#31.
The only issue with this approach is the mapping between the singular form of an entity (company
, which is included in the sideloading reference) and the plural form, or "domain" (companies
), see the RFC for more context.
Now how will we return the data? I personally don't see a use case (yet) to not return the data merged.
example hook
const QUERY = () => ({
domain: 'projects',
action: 'list',
options: {
include: 'participant'
}
});
const { loading, error, data } = useQuery(QUERY)
example data
returned from the hook
[
{
id: '708c8008-3455-49a9-b66a-5222bcadb0cc',
title: 'Test project'
participant: {
type: 'user',
id: '82200479-576f-462c-ad38-aad52da23c55',
lastName: 'Smith'
}
},
{
id: 'e6538393-aa7e-4ec2-870b-f75b3d85f706',
title: 'Test project'
participant: {
type: 'user',
id: '3defbb8a-c1db-465c-bc25-b36f48894e23',
lastName: 'Wick'
}
}
]
So what do you guys think? Is this a good approach? Do you see any caveats that could come back and haunt us?
We should save the API response as entities in the store. This way it will be easier to access and share them.
We should expose the store as a middleware to avoid creating multiple redux stores and allow access to it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.