-
-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
farmOS 2.x #39
Comments
ExampleI sketched up some of these ideas in my local farmOS.py... here's some example usage: Overall this is working great. The But there are a few rough spots: Resource Types & Iterators vs Pages Resource types@mstenta @jgaehring I'm curious what you guys think of this issue in particular. It will have the most overlap with farmOS.js. The I believe this creates a problem once we start considering logs (or any record) that references other JSONAPI resources (assets, terms, etc.) For context, here are the current (I think this issue touches on the same problem: https://www.drupal.org/project/drupal/issues/3105318) "relationships":{
"log_type":{
"data":{
"type":"log_type--log_type",
"id":"5cf12ac8-d6a6-4164-8eff-f60a08589a15"
},
"links":{
"related":{
"href":"http://localhost/api/log/input/2d2c2b71-171e-4ef1-8b1e-0c2d68af12bd/log_type"
},
"self":{
"href":"http://localhost/api/log/input/2d2c2b71-171e-4ef1-8b1e-0c2d68af12bd/relationships/log_type"
}
}
},
"category":{
"data":[
{
"type":"taxonomy_term--log_category",
"id":"52c960eb-fd8b-4765-b843-e5c875d4088e"
},
{
"type":"taxonomy_term--log_category",
"id":"7ecf8f81-1c5c-44e6-86bd-6b74f41fabd7"
}
],
"links":{
"related":{
"href":"http://localhost/api/log/input/2d2c2b71-171e-4ef1-8b1e-0c2d68af12bd/category"
},
"self":{
"href":"http://localhost/api/log/input/2d2c2b71-171e-4ef1-8b1e-0c2d68af12bd/relationships/category"
}
}
},
... other relationships: owner, uid, log_type
} To load the name of the log's categories via the client the user needs to know that # Get a log
log = client.log.get('input', 'UUID')
log_data = log['data']
# alias the terms
terms = log_data['relationships']['category']['data']
# Not possible; cannot simply reference the category "type"
cat = client.term.get(terms[0]['type'], terms[0]['id'])
# Load a single category; 'log_category' is assumed.
cat = client.term.get('log_category'), terms[0]['id'])
# OR to load both:
term_ids = [term[0]['id'], term[1]['id']]
cats = client.term.get('log_category', filter('category.id', [term_ids], 'IN')) For log categories it might be an OK assumption that users know categories are in the But for assets, a log can reference any type of asset. This will make it much harder to load a specific asset referenced by a log: # Get a log
log = client.log.get('input', 'UUID')
log_data = log['data']
# Not possible; cannot simply reference the asset "type"
asset = log_data['relationships']['asset']['data'][0]
asset_info = client.asset.get(asset['type'], asset['id'])
# Parse the bundle from "type"
asset = log_data['relationships']['asset']['data'][0]
asset_type = parse_bundle_from_type(asset['type'])
asset_info = client.asset(asset_type, asset['id']) Some potential solutions:
Iterators vs PagesThe The limitation with this is that any additional A solution to this could be providing an additional all_logs = []
for page in client.log.iterate_page('input'):
logs += page['data']
includes = page['included']
if 'omitted' in page['meta']:
# alert user that some records were omitted. And a separate |
Not sure I totally grok the issue with resource types. I guess I'm not sure where that Maybe it would be more helpful to discuss in live-time tomorrow? |
Yea, |
@jgaehring To summarize (after chatting with @paul121 and getting up to speed myself)... JSON:API has some rules about how records are structured that differ from the current farmOS 1.x API implementation provided via the Specifically:
|
In the interest of keeping things simple, I think this makes the most sense. I'm hesitant to start messing with resource aliases via JSON:API Extras module... after having seen just how complicated that can be in 1.x / |
I released an alpha version that implements much of what I had outlined above: https://github.com/farmOS/farmOS.py/releases/tag/v1.0.0-alpha.1 Some remaining questions/issues:
|
Moving JSON schema support to a later version. Closing this issue. |
Opening this issue to track implementation of the farmOS 2.x API in this library. See https://www.drupal.org/project/farm/issues/3151243 for more info.
In this process I'd like to address:
For this first pass lets not address, but keep in mind:
Perhaps we can use https://github.com/qvantel/jsonapi-client for inspiration when implementing these ideas in the future. It looks like a good example for supporting both synchronous (via requests) and async (via asyncio) requests, as well as providing more of an object-oriented API more reflective of JSON:API.
Server API Changes
We will likely maintain support for farmOS 1.x. The server version can be determined by checking the API version included in
/api
(an alias to/farm.json
) before including the necessary client methods. If applications need to support multiple server versions (such as farmOS Aggregator), this will be possible, but application code should be defensive in supporting different response formats returned via this library.Response formats
Fetching an endpoint such as
/api/log/{type}
will return:Format of an individual record within the
data
list:Breaking changes
These will likely affect the API of the client library:
/log.json
,/farm_asset.json
). Consequently, the client API will require the entity bundle to be specified eg:client.log.get(type='observation')
Proposal
"Raw" requests
Return entire JSON response for these requests (all keys):
Pagination
Drupal docs: https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/pagination
By default no pagination will take place. This gives the user full control over requests.
Iterators
Quoting @symbioquine fom #31
Iterators make it easy!
Manual pagination
Users can implement pagination by passing
page[limit]
andpage[offset]
filters toclient.log.get(type, filters)
. The user can keep track of pages internally OR;Since the entire response is returned, users can request more data if there is a
next
link available. Theclient.fetch()
function helps facilitate this. Without the helper function, thepage[offset]
andpage[limit]
params would need to be parsed from thenext
link before constructing another request - why not use the URL that is already built??Filters
Drupal docs (see Filtering, Sorting and Includes): https://www.drupal.org/docs/core-modules-and-themes/core-modules/jsonapi-module/filtering
(Please read the Drupal docs to understand how JSONAPI Filters work!!)
Filters can still be implemented as a Dictionary of query params to include, so no changes there. But a
farmOS.Filter
helper function would be useful in generating more complicated filters:The text was updated successfully, but these errors were encountered: