API Model Defintions - api

Typically when I am making API calls I am using javascript (ajax). JSON doesn't include value types of properties, and so everything is passed as a string.
Since I manage my own API I create request-able models that will tell you the definition of a model.
For example Id value type is int, StartDate value type is date.
I use the property types to automate form creation.
Is there a standard as to how to do this? My way works, but I'd prefer to be doing this by the book if it already exists.

OpenAPI is a standard you could follow. If you also make use of Swagger, it will allow you to produce a JSON schema which can be used in generating forms.

The hard part is typings are done at compilation and JS does that in browser.
You could use a typing model agent such as graphQL that adds a definition for those types ahead of time. Those definitions can then be dynamically fetched and enforced using typescript and a tool like apollo.
If you dont want to use typescript or graphql you could use something like mongoose schema and expose the schema on an endpoint then have your front end rebuild the schema dynamically to check types by casting when creating new objects.
Personally ive done this old fashion way by writing my own form schema and enforce the form types strictly on the front end by interpreting the fieldTypes
// returned from API somewhere
const fields = [{
type: 'input',
name: 'firstName'
rank: 0,
validation: '/^[a-zA-Z\s]+$/'
}]
Edit:
Found this great library that exports typed interfaces based on graphQL models.
https://github.com/avantcredit/gql2ts

Related

How to do right rest api update?

I am developing rest api update method for user profile resource user/profile. I am disappointed what http method should i use. Update contains some required attributes so it more PUT request, where client need to fill all attributes. But how it can extend attributes in future. If i will decide to add new attribute then it will automatically clear because client is not implement it yet.
But what if this new attribute has default value or is set by another route?
Can i use PUT with not stricting number of attributes and use old data if new isn't come in request. Or how it can be done normally?
HTTP is an application whose application domain is the transfer of documents over a network -- Webber, 2011.
PUT is the appropriate method to use when "saving" a new version of a document onto a web server.
how it can extend attributes in future.
You design your schemas to be forward and backward compatible; in practice, what this means is that you can add new optional elements with reasonable default values. When you need to add a new required element, you change the name of the schema.
You'll find prior art in this topic by searching XML literature for must ignore.
You understand correctly: PUT is for complete replacement, so values that you don't include would be lost.
Instead, use the PATCH method, which is for making partial updates. You can update only the properties you include values for.

Play: Automating test data setup

I have a playframework project that has reached beta/user testing.
For this testing we require test data to exist in the environment
I am looking for a way to automate this via scripts.
The best way will be via call's to the API passing the correctly shaped data based on the models in the project (thus dependant on the project not external).
Are there any existing SBT plugins that I could utilise that would be able to create the appropriate JSON and pass it to the API to setup the environment
Why do you need a plugin for this? I think what you want to do is to have a set of Json, then call the end-points and see what is the response from the back-end. In case of "setting up" based on a call that has a Json, you could use FakeRequest in your tests:
val application = newGuiceApplicationBuilder().build()
val response = route(application, FakeRequest(POST, "/end-point")).get
contentAsString(response) must include("where is Json")
In your test you can also test the response from the back-end and the Json you are feeding it:
Create a set of Json using Writes, based on a case class you are using in the back-end. You could also purposely create an invalid Json as well, that misses a field for example; or has an invalid structure.
Use Table driven testing and sending FakeRequest with the body/header containing your Json; and then checking it against the expected results.
I'm on the move, when I get home, I can write an example code here.

Ember change normalizeResponse based on queried model

I'm using a second datastore with my Ember app, so I can communicate with a separate external API. I have no control over this API.
With a DS.JSONSerializer I can add some missing properties like id:
normalizeResponse(store, primaryModelClass, payload, id, requestType) {
if (requestType == 'query') {
payload.forEach(function(el, index) {
payload[index].id = index
})
}
Now I can do some different tricks for each different requestType. But every response is parsed. Now sometimes a response from one request needs to be parsed differently.
So what I am trying to do is change the normalizeResponse functionality for each different request path (mapped to a fake model using pathForType in an adapter for this store). But the argument store is always the same (obviously) and the argument promaryModelClass is always "unknown mixin" - not sure if this can be any help.
How can I find what model was requested? With this information I could do a switch() in normalizeResponse.
Is there a different way to achieve my goal that does not require me to make a separate adapter for every path/model?
There are over a dozen normalize functions available. Something should work for what I am trying to achieve.
I think this is a great example of a use case of not using ember data.
Assuming that you have models A,B,C that are all working great with ember data, leave those alone.
I'd create a separate service and make raw requests to that different endpoint. So you'd replace this.store.query('thing', {args}) with a separate service that uses ember-ajax (or ember-fetch or whatever). If you need, you can use that service to hold the data that you need (Ember-data is just a service anyway) or you can create models and push them into the store manually.
Without knowing more about your exact situation, hard to give a specific code/advice, but I'd just avoid this problem and write your own custom service.
You can use primaryModelClass.modelName.

Specifying a GeoTools read-only DataSource

Using a call such as:
DataStore dataStore = DataStoreFinder.getDataStore(map);
Is there an entry I can make to the map to make the datastore read-only? The only thing I have seen is the URL to specify the name for the datasource.
I imagine that the reason a map is used to send in arguments is that various data sources require different parameters. I am dealing with shape files right now and have not seen any way to specify it.
Thanks.
A DataStore doesn't have a notion of being read-only or read-write. On the other hand, the classes which access a feature type do; there is a difference between a FeatureSource and a FeatureStore. The former class does not have any write/update functions. A high-level description is here.
By default datastore.getFeatureSource returns its result cast as a FeatureSource (read-only). If you want to have write-access, you have to try and cast the FeatureSource to a FeatureStore. As a note, not all DataStore implementations provide write-access.

store.loadData not defined. How to load data into store Sencha Architect

In the past, I created my stores using Ext.create('Ext.data.Store', ...
and when I wanted to load data the was contained in a JSON loaded object, all I needed to do was MyStore.loadData(myDataObj);
This does not work with the stores you define in Sencha Architect, you get Not defined error for loadData.
I have a custom Ext.Ajax routine I use to get the data that does not lend itself to being defined in a stores proxy. My data is in the proper JSON format, but I have had no luck finding a way to force load data into a store without using a store proxy.
I was able to get MyStore.add({--json string ...}) to work, but this only adds a single record.
Why is store.loadData() not suppored ??? What can I use instead???
use store.setData assuming you are using a Touch project.
I have read the Sencha API docs. The issue here is that the Store.loadData does not appear to be valid (ie Un-defined) when referenced in a user defined function in Sencha Architect. I have not been able to find a way to take a variable that has a valid JSON object and load it into s store. The only method I believe would work is if I created the stores in a function, but that would defeat the awesome UI the architect provides.