I'm currently building a mutation that deletes a node.
I looked into the NODE_DELETE mutator configuration, but it specifies it needs a parentName, parentID and connectionName.
Why does deleting a node needs theses fields ? As Relay uses global IDs, it should be fairly easy to delete a node from all connections and/or all fields it is being referenced in.
See the documentation :
Relay NODE_DELETE documentation
Your intuition is correct. Those fields are redundant for the purpose of deleting node from data store, only config.deletedIDFieldName is used during such operation (details in writeRelayUpdatePayload module).
However you can't leave other fields unfilled, because they are still required during validation of your mutation that extends RelayMutation class. I have no idea where this inconsistency comes from, but it's worth noting that Relay team changed the direction of development and RelayMutation will get deprecated.
RelayMutation and fat/tracked queries. Future releases will deprecate
this API in favor of a static mutation API. We recommend using
RelayGraphQLMutation to ease the transition to new mutations.
source: Related issue on github
After quick look in Relay's source it seems this transitional API does not use the old method of configs validation, but I haven't got a chance to experiment with it yet, so you can confirm it yourself.
Related
We are considering changing our rails app (which relies heavily on Nested Attributes-style data creation) to use JSONAPI instead. However, it seems that JSONAPI may not support this style of document creation/updating?
I've read around and this is sometimes referred to as "compound documents" or "sideposting". My research has been inconclusive, so posting here in hopes that someone out there knows the deal.
For example if in our app we had a Person that has many PhoneNumber, I would like to be able to send a PATCH to /person/1 that had information relating to phone numbers. RoR Nested Attributes allows for sending new phone numbers (ones without an id), modifying existing ones, and deleting existing ones. Is there an equivalent for this in JSONAPI?
If not, how would a client go about submitting this data to the server? A separate request for every object? On some of our pages that could result in 100 plus requests... and each one would need to be managed for errors indivdually?
JSON:API specification v1.0 does not support to create, update or delete more than one resource with one request. So if your server only supports that version of the specification without any custom modification the client would need to submit separate requests for each resource that should be created, updated or deleted. That means the client needs to handle errors for each one individually. This may include rolling back partial changes if one requests fails in a series of related updates.
The missing support for atomic operations is known to be a problematic limitation for some use cases. It should be resolved with the upcoming v1.1. This version is planned to add extensions to the specification. An extension can extend the specification. An extension Atomic Opersions is proposed, which would add support for creating, updating and deleting multiple resources with one request. A client would be able to provide a list of mutations that must be processed in a linear and atomic manner by matter by a server implementing that extension. This means that the modifications are processed in order and will either completely succeed or fail together.
I have been given an assignment. It pertains to integration/transformation using xml/xslt and is deliberately vague. I have been given a sample integration (shown below) and I have been tasked with listing several questions I would ask before delivering this design,
The hypothetical integration
Data Source --> Mapping ---> output
The question is so vague I couldn't think much. I am not looking for anyone to plagiarise from, but I am hoping someone could post some sample questions to help me get started.
Pertinent Information
Note: Stack Overflow is not a place for you to cheat on an interview process. I am providing this information for other users who are looking to familiarize themselves with integrations. If you don't already know what questions to ask here, and are applying for an SOA job, you will likely be fired within a month. Dishonesty can cost a business a lot of money, and if you cheat your way into a job don't be surprised when you get blackballed or worse - perpetuate a harmful stereotype.
There are a variety of questions you would need to ask before implementing this type of integration. Here are a few things that come to mind.
1. What type of integration is this?
There are a variety of different integration paradigms. I would need to know if it is
An app/request driven orchestration
A scheduled orchestration
A file transfer
A pub/sub subscription
2. Is it invoked or triggered
An invoked integration is one that begins when it is specifically called. If I had a REST service that returned a list of countries, and your call that service every time a button was clicked that would be an invocation based integration.
Integrations can also be trigger based. Let's say you had a table that stored customers. You want to send an email whenever a new customer is added to that table. If you set your initial data source (adapter) as a trigger source on a row insert you could essentially have the integration run without explicitly being triggered.
3. What is the data source?
I would need to know if the data source is REST, SOAP, a database (DB2, MySQL, Oracle DB, etc), a customer adapter, etc. IS the data source adapter the entry point here or is the initial app adapter not shown?
4. What is the schema definition of the request / response body, and how is it specified?
You have a data source (which appears to be your initial app adapter), then you have a transformation, and a response. You can't do any transformation (or build an integration) if you don't know what the input / output will be (with some exceptions). This is really a multi level question.
How do I specify the request and response? Do I need to draft a JSON Schema or XSD document? Some platforms allow you to specify XML or JSON and they will do it's best to generate a schema for you.
What is the request and response content type? You can specify the request / response in whatever format is acceptable, but that doesn't necessarily mean that is the request / response type. For example some platforms let you specify your request body with an XSD but the content type is actually JSON. Is it XML, JSON, Plain Text, other?
5. What about other parameters
Basically, what does the endpoint look like? Are there query parameters, template parameters, custom header parameters, etc?
6. How is this integration secured?
Is this integration security using OAuth? If so what type of tokens are used (JWT, etc)? Does the integration use basic authentication?
Based off the answers to the previous questions you may then have questions about the mapping. For example, if I was provided a schema definition for the output that had an attribute called "zip" I might ask how they wish to format that, etc. I wouldn't ask anything about what technology is used for the mapping. Firstly, because it'as almost always XPath/XSLT, secondly that isn't something you need to know, it's something you would figure out on your own.
I am looking for solution of logging data changes for public API.
There is a need to tell client app which tables form db has changed and need to be synchronised since the app synchronised last time and also need to be for specific brand and country.
Current Solution:
Version table with class_names of models which is touched from every model on create, delete, touch and save action.
When we are touching version for specific model we also look at the reflected associations and touch them too.
Version model is scoped to brand and country
REST API is responding to a request that includes last_sync_at:timestamp, brand and country
Rails look at Version with given attributes and return class_names of models which were changed since lans_sync_at timestamp.
This solution works but the problem is performance and is also hard to maintenance.
UPDATE 1:
Maybe the simple question is.
What is the best practice how to find out and tell frontend apps when and what needs to be synchronized. In terms of whole concept.
Conditions:
Front end apps needs to download only their own content changes not whole dataset.
Does not invoked synchronization when application from different country or brand needs to be synchronized.
Thank you.
I think that the best solution would be to use redis (or some other key-value store) and save your information there. Writing to redis is much faster than any sql db. You can write some service class that would save the data like:
RegisterTableUpdate.set(table_name, country_id, brand_id, timestamp)
Such call would save given timestamp under key that could look like i.e. table-update-1-1-users, where first number is country id, second number is brand id, followed by table name (or you could use country and brand names if needed). If you would like to find out which tables have changed you would just need to find redis keys with query "table-update-1-1-*", iterate through them and check which are newer than timestamp sent through api.
It is worth to rmember that redis is not as reliable as sql databases. Its reliability depends on configuration so you might want to read redis guidelines and decide if you would like to go for it.
You can take advantage of the fact that ActiveModel automatically logs every time it updates a table row (the 'Updated at' column)
When checking what needs to be updated, select the objects you are interested in and compare their 'Updated at' with the timestamp from the client app
The advantage of this approach is that you don't need to keep an additional table that lists all the updates on models, which should speed things up for the API users and be easier to maintain.
The disadvantage is that you cannot see the changes in data over time, you only know that a change occurred and you can access the latest version. If you need to track changes in data over time efficiently, than I'm afraid you'll have to rework things from the top.
(read last part - this is what you are interested in)
I would recommend that you use the decorator design pattern for changing the client queries. So the client sends a query of what he wants and the server decides what to give him based on the client's last update.
so:
the client sends a query that includes the time it last synched
the server sees the query and takes into account the client's nature (device-country)
the server decorates (changes accordingly) the query to request from the DB only the relevant data, and if that is not possible:
after the data are returned from the database manager they are trimmed to be relevant to where they are going
returns to the client all the new stuff that the client cares about.
I assume that you have a time entered field on your DB entries.
In that case the "decoration" of the query (abstractly) would be just to add something like a "WHERE" clause in your query and state you want data entered after the last update.
Finally, if you want that to be done for many devices/locales/whatever implement a decorator for the query and the result of the query and serve them to your clients as they should be served. (Keep in mind that in contrast with a subclassing approach you will only have to implement one decorator for each device/locale/whatever - not for all combinations!
Hope this helped!
I am going to develop an iOS app for a web application. (The web app uses code igniter)
I am going to create an API Service that the iOS app will consume.
I am thinking of creating an api version, so when the web api changes, the iOS app will know.
Concerns:
iOS app will need to be updated when web application api changes (unless I keep legacy api available..Is this a good option)
If iOS app is updated when web app api is NOT updated this will cause a problem too
Should my iOS app specify the version of the api it requires?
If iOS app api is less than web api: Display Message: Please update iOS app
If iOS app api is greater than web api: Display Message: Please update web app
Is this best practice?
Should I make an api class for every version and extend the previous version and override methods when they change?
Example
ApiV1 extends CI_Controller
{
function list_customers(){//Code}
function saveSale() {//Code}
}
ApiV2 extends ApiV1
{
function saveSale()
{
//New way of saving sale
}
}
Also what happens if I make a change to the database structure where the v1 api will no longer work? (Example, changed the name of a database table?)
In general, you want to create a fairly loose coupling between your service API and your client. As a rule, there will be multiple versions of the client always floating around in the wild, and you want to force upgrades on users as rarely as possible.
A full rev of an API version is actually somewhat rare in web services, and usually only corresponds to significant changes to the data model, security model, etc. Allowing multiple versions to coexist may require some extra work on the service, but can be worth it to allow existing clients to keep working.
To that end, think carefully in the design up front about the "model" you're using as an abstract entity independent of the current client UI needs. (If you want more specific thinking around your particular case, you may wish to post a separate question about modeling your needs.) But don't worry too much about solving all of the needs forever in advance, because requirements will inevitably change.
Once you've done this, do prepare for the future by building some notion of versioning into the service API. Some things to consider:
An explicit version as part of the URL scheme or specified initially during e.g. auth handshake. This is a way to cleanly namespacing what the client accesses. (The former would result in explicit URL routing on the service, the latter would require more gymnastics to route after cracking an auth token.)
A known error response that means "this API call is obsolete", which an earlier client can recognize to tell the user that their client requires an update
On the service, your design can be as explicit as you note, with a controller with method overrides, but at a little higher level: the saveSale method is somewhat unlikely to behave very differently between versions. It would seem more likely to have a saveSale method in V1 that does the baseline thing, and then maybe e.g. saves some extra bit of data in V2. When that happens, the code might just have conditional branching if that extra bit of data is present. All of this is another way of saying that a service API doesn't actually change incompatibly that often. list_customers could return more information over time. That doesn't necessarily mean that your API needs a new version or that old clients shouldn't just ignore any extra information they don't need.
Re: your final question about database table names. Those may change internally, but you aren't required to map those explicitly to what the client sees. An API is a stable interface that should ideally hide the implementation details of your ever-evolving service.
You'll choose to rev the API when, as a whole, you decide that the overall picture of what the API needs to do is significantly changed enough that it cannot peacefully serve the needs of existing clients. You'll choose to deprecate and obsolete certain client versions when you decide that maintaining support for them on the service is causing you more headache than the install base is worth (a very business/case specific issue).
Good luck.
I don't know if having your iOS app specify the version of the api it requires is good practice but, I would think it is a safe play; one concern though, if you frequently update your api then it won't be long before it becomes a hassle/anoying having to frequently update the app.
I would keep legacy method name(s) and add method(s) with a different name to avoid users having to update to new version of the app when you change the web api.
I would not create an api class for every version to extend the previous version of the api.
I would say changing the database structure would require changing/updating your api, unless you also want to keep legacy version of your table name or definition or data, which it is not feasible/practical/convenient in most instances/situations. In this case you want your users to update to the new app and api.
Look at this answer that points to a presentation of API design principles and practices.
I do not know as to what best practice, however I would definitely recommend that your iOS app keep track of what version of your API it is looking for, and specifically request that version. For instance, a URL of '/api/v1/....'. This way When you update your API, you can simply up it to a different version ('/api/v2/...', and leave v1 alone for the iOS app to consume. Obviously you should display a message to the iOS user to upgrade (perhaps a meta field in your response) when a newer version exists.
This approach should allow you to continue development on your API without cutting off people who haven't been able to upgrade their app.
Update
Just one more thing; if you make a change that will make a previous version inoperable (such as changing table names, schema, etc), you should have a status code for that that your iOS app will understand. Something associated with the message 'This API version has been retired. You must update'.
I would also recommend a similar header (or something) when an API is deprecated (ie, a new version exists). Obviously continue to provided the requested information/actions, however a warning that the version is not supported anymore and that they should upgrade (or even triggering something in your app to upgrade) can be helpful.
I've read the documentation and samples multiple times and can't find out how to do this.,
I'm trying to wire up DB4O to use my own custom Id field. based on the documentation you can define your own IDs but as far as I can tell they won't replace Db4o's internal IDs, As in it won't actually use those Ids to identify the objects.
Basically all the examples do are tell Db4o to generate some sort of unique id and index it, I don't see anywhere on how to tell it that this is the ID that you should use.
Is it possible to have our own IDs on our model replace the internal IDs used to keep track of the relationships?
we need to have our own Ids since our system relies heavily on REST.
There no direct support for this. You need to create your own mechanism.
Simplest way: Use Guid on .NET. Or use a UUID in Java. In Java: Add UUID-Support: configuration.common().add(new UuidSupport());
Use callback to create new id's. Doesn't not work in TCP client/server.
See also this page.
Side note: You build a REST app. How many request does it need to handle? db4o is internally inherently single threaded. It can only handle a very limited load.