How to manage database version in REST API - mongodb

Suppose I have an mobile app named APPO v1 which take resources from a REST API v1. There are about thousands of user at APPO v1
Now I am developing APPO v2 with API v2. Both api and app have new functionality and new fields in database. Some fields are modified too.
API v1 DATABASE SCHEMA:
{
"user_id": NumberLong(616),
"name": "XYZ",
"city":"Dhaka"
"password": "raw password: 12345678",
"gender": ""
}
API v2 DATABASE SCHEMA:
{
"user_id": "STRING HASH",
"name": "XYZ",
"address":"98/3 Circle road, Dhaka 1209"
"password": "MD5 HASH",
"NEW_FIELD": NumberLong(5)
"ANOTHER_FIELD": ""
}
Changes:
data type of user id is changed
Short city name replaced with address string
password format is changed
gender field is removed
some new field is added
How to handle the database ?
My solution 1: Separate DB by v1 & v2. Re-format the v1 and paste into v2
Problem with solution 1: All user will not update the app in a day. If a v1 user update their app to v2 they may loose the recent data. I have to make a synchronizer between two DB
My Solution 2: Since my app v1 takes raw password I have to keep this right away. I should marge the both SCHEMA
{
"user_id": NumberLong(616),
"user_id_hash": "STRING HASH",
"name": "XYZ",
"city":"Dhaka"
"address":"98/3 Circle road, Dhaka 1209"
"password": "raw password: 12345678"
"password_md5": "MD5 FORMAT",
"gender": ""
"NEW_FIELD": NumberLong(5)
"ANOTHER_FIELD": ""
}
Problem with solution 2: It will create huge garbage when the version will greater than 10 or more. At v10 i dont need v6,v5.......v1 Data
NOTE: Fields have nothing to do with REST model. All are example fields for such kind of situation
I am totally confused how to deal with that. I really appreciate your patient and your suggestion!
Thanks in advance !

i have a solution, if you don't want to denormalize the database. You can use bridge pattern for this problem. When you have same type of multiple problems/implementations(API v1 & API v2...etc), but client will be connected with only one implementation (ex. API v1 ), you need to implement a bridge object, which will understand, where to place the client, i mean required implementation. in technically, you have to write the business logic for each problem separately but only one REST Api is enough to redirect the client to that implementation. Thanks

Related

How to Get / Update Customer GL Account info via Rest API

I'm trying to figure out how to Get and Update a Customer's GL Accounts info via Rest API.
As seen in this screenshot, a Customer's GL Accounts section has fields such as:
AR Account
AR Sub
Sales Account
Sales Sub
etc.
Via Rest API, where can I retrieve this Customer's above info, and how can I update them accordingly?
I'm able to perform CRUD for all the other Customer entity fields, but I'm quite lost regarding how per Customer GL Accounts can be retrieved and updated. Looking for any help to point me to the right direction.
Those fields are not the part of the Default endpoint, so you need some tricks to retrieve or update them.
You can either use custom endpoint or retrieve/update these fields using 'Custom' fields collection.
As for custom endpoint, here is the link that can help.
As for the custom fields, you can retrieve the values like that:
GET: {{sitename}}/entity/Default/20.200.001/Customer?$custom=DefLocation.CSalesAcctID, DefLocation.CARAccountID
Response:
{
"id": "90f25585-fbc0-eb11-9d4f-3ce1a14ed5bf",
"CustomerID": {
"value": "AAA"
},
"custom": {
"DefLocation": {
"CSalesAcctID": {
"type": "CustomStringField",
"value": "40000"
},
"CARAccountID": {
"type": "CustomStringField",
"value": "11000"
}
}
}
}
See here how to get the field names.
To update the fields you send them in the body the same way you get them in the response

Best practice to return Type id descriptions for api consumers

I am developing an api for clients to consume.
Some of the objects e.g. telephone, where a person could have more than one telephone will have multiple type id's. I have a list of telephone types server side and the consumer will be required to either pass no value and it will default this or pass an id to represent the correct value. Now this in itself is not my issue however when you expand the type id's across many, many objects you arrive at my question.
If as a developer you're consuming the API data, would you prefer a single URI end point to retrieve all the type id's and descriptions, or multiple end points to call for each type id list (which would and has driven me nuts previously with other API's) or just document all the Id's (although this is a moving target always)
Basically clients will push their data into the system via the API, we will then process the data in some way and they will build reports from the data processed.
So what's preferred?
Single end point
GET: domain/root/allTypes
{
"TelephoneTypes":[
{"id": 123, "description":"Home"},
...
{"id": 789, "description":"Mobile"}
]
},
"EmailTypes":[
{"id": 234, "description":"personal"},
...
{"id": 567, "description":"work"}
]
}
Or
Multiple end points
GET: domain/root/telephone/types
{
"TelephoneTypes":[
{"id": 123, "description":"Home"},
...
{"id": 789, "description":"Mobile"}
]
}
GET: domain/root/email/types
{
"EmailTypes":[
{"id": 234, "description":"personal"},
...
{"id": 567, "description":"work"}
]
}
I'm sure context will effect the outcome and I've tried to give as simple a scope to the question. I'm really interested in the general preferred consumption approach as I've used several API's and added to many more but this is a greenfield project so I want to try and find the overall preferred method to passify the end users/developers and keep my sanity :)

Change the mapping of a field in Kibana from String to Double

I am capturing live streaming of data and processing it. I configured my logstash.conf file.
I started my ElasticSearch, Logstash and Kibana.
I created my index in kibana and when I do a get index in the dev tools,
I have something like this
"message": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
I want to change the type of message from String to Double. How can I do it?
You can't change mapping after an index is created - you'll have to create the mapping yourself in a new index explicitly create the fields/types you need:
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
then re-index from the old to the new index:
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html
Note the type you want is 'double' not 'Double':
https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html
Changing the data type of a field in Elasticsearch(ES) is a breaking change. In your case, you need an update the mapping and update in ES.
Please use https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-get-mapping.html to verify, that mapping is updated successfully in ES.
Reindex API requires _source to be enabled, Please refer https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-source-field.html for more information on _source field and whether it's enabled in your case.
If it's not enabled in your case, then the only option you have it to delete the old index(which has older mapping) and create it again with the new mapping.
Let me know if you have any doubt or face any issue implementing this.

Designing RESTful shopping cart

I am building a single page application for booking hotel conference rooms and am not sure how to set it up, or even if RESTful is the proper approach. There will be four steps to this SPA:
The user chooses a date (available dates come from server - some days could be fully booked).
The user chooses a conference room (conference rooms available at this hotel on the date chosen in step 1 are retrieved from the server).
The user enters their name, address, billing info.
User sees confirmation page.
This same SPA will be used by multiple hotels with the same database back-end, and for the front-end I was thinking Ember.
Is RESTful the right approach for this application?
I was thinking:
GET /dates?hotel_id=xxx (should I pass the hotel ID in the URL vs. in headers vs. in the body?)
GET /rooms?hotel_id=xxx&date=yyy (should I be passing the date and hotel_id in, or somehow remember it on the server?)
POST /order with body: {date, conference_room_id, name/address/billing info}, returns { confirmation_id }
Should the name/address/billing info be put into a separate POST?
Thank you for your advice.
In a REST(ful) framework there's no concept of session. Every request must send all the required information in order to identify a resource.
I'll post an example below, based on requirements you provided.
GET /hotels/{hotel_id}/dates
Path params:
hotel_id (required)
Query params:
startDate (optional, default: today)
endDate (optional, default (example): today + 3 months)
status (optional, "available"/"booked"/"all", default: "all")
Response body: [{"id":"20160503", "dateStr":"May 5th 2016", "status": "available"}]
GET /hotels/{hotel_id}/dates/{date_id}/rooms
Path params:
hotel_id (required)
date_id (required)
Query params:
status (optional, "booked"/"available"/"all", default:"all")
Response body: [{"id": "12", "status": "available", "reservationId": ""}, {"id: "13", "status": "booked", "reservationId" : "123"}]
Note: this kind of implementation allows to list different combinations of dates and rooms (e.g. booked rooms in available days).
POST /hotels/{hotel_id}/reservations
Path params:
hotel_id(required)
Request body: {"dateId":"20160503", "roomId":"12", "firstName":"John", "lastName":"Doe", "address": "xxx", "vatNumber" : "yyy", "companyName": "zzz"}
Note: if you store billing addresses as separate entities (e.g. if your server is required to "remember" them), then it can be useful to implement POST and GET services for billing addresses (/billing) and refer to them with proper identifiers.
Response body: {"reservationId" : "324"}
GET /hotels/{hotel_id}/reservations/{reservation_id}
Path params:
hotel_id(required)
reservation_id (required)
Response body: {"dateId":"20160503", "roomId":"12", "firstName":"John", "lastName":"Doe", "address": "xxx", "vatNumber" : "yyy", "companyName": "zzz"} (same as POST request body)
GET /dates?hotel_id=xxx (should I pass the hotel ID in the URL vs. in headers vs. in the body?)
GET /rooms?hotel_id=xxx&date=yyy (should I be passing the date and hotel_id in, or somehow remember it on the server?)
POST /order with body: {date, conference_room_id, name/address/billing info}, returns { confirmation_id }
Your solution can use Restful API approach. Because it enable any other component to directly call your APIs. It can be APP, or a website or plugin or just another java program connected to internet, they just need to trigger your API and they are done.
URL you mentioned for your application, please note that one should use resource-based URL approach while building RESTful api.
GET /date/hotels/ -> Gives you all available rooms in all hotels on that particular day
GET /dates/hotels/ -> Give you list of available rooms for a particular hotel (Use dates/hotel_id instead of dates/?hotel_id=xxx). Parameter should be used to filter your result. E.g. dates/hotels/hotel_id?PIN=142: This should gives you hotel whose pin matches 142
dates/hotels?MAX_RECORD=50: This should give you list of hotels but limit to 50
You can find more about creating resource-based Restful API https://www.youtube.com/playlist?list=PLqq-6Pq4lTTZh5U8RbdXq0WaYvZBz2rbn
I would put the "Selects" into GETs as designed.
e.g. dates GET /hotel/:id/date -> Get all available dates
rooms GET /hotel/:id/date/:date/rooms -> Get all available rooms
per design in a RESTful API GET is defined for requesting data.
For the POST I would not breakdown into a seperate POST but you can put some parameter like hotel_id or date into the URL.
Best
Fabian

Neo4J REST Unique Nodes

My question is two parts:
First, when trying to create a unique node using the REST Interface like below...
http://localhost:7474/db/data/index/node/people?uniqueness=create_or_fail
What is the meaning of the "person" portion of the URL. I'm under the impression that it is a label but I'm not sure.
Second, if it is indeed a label, when I execute the following REST call...
http://localhost:7474/db/data/index/node/Test?uniqueness=create_or_fail
with this payload...
{
key: "name",
value: "test",
properties:
{
"lastName": "test",
"name": "test",
"type": "test",
"firstName": "test"
}
}
A node is created but does not have an associated label. It creates a label-less node that does still enforce uniqueness. How do I create a unique node using the REST API with a label?
I'm using neo4j 2.0.
You are correct. When you send in JSON, it will create the node, or fail if it already exists using the index label 'people'
When sending, you need to have in your object a "key" and "value" which denotes how to do the index matching.
How are you determining that the node has no label? In the REST documentation, I can see that the labels is a different URL call for a node, have you checked there?