{"id":802,"date":"2020-10-10T23:00:18","date_gmt":"2020-10-11T03:00:18","guid":{"rendered":"http:\/\/salzlechner.com\/dev\/?p=802"},"modified":"2020-10-11T06:26:37","modified_gmt":"2020-10-11T10:26:37","slug":"starzen-rest-library-for-dataflex-webapp-adding-a-database","status":"publish","type":"post","link":"http:\/\/salzlechner.com\/dev\/2020\/10\/10\/starzen-rest-library-for-dataflex-webapp-adding-a-database\/","title":{"rendered":"StarZen REST library for DataFlex WebApp \u2013 Adding a database"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;3.22&#8243;][et_pb_row _builder_version=&#8221;3.26.7&#8243; background_size=&#8221;initial&#8221; background_position=&#8221;top_left&#8221; background_repeat=&#8221;repeat&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;3.25&#8243; custom_padding=&#8221;|||&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_text _builder_version=&#8221;3.26.7&#8243; z_index_tablet=&#8221;500&#8243; text_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; text_text_shadow_vertical_length_tablet=&#8221;0px&#8221; text_text_shadow_blur_strength_tablet=&#8221;1px&#8221; link_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; link_text_shadow_vertical_length_tablet=&#8221;0px&#8221; link_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ul_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ul_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ul_text_shadow_blur_strength_tablet=&#8221;1px&#8221; ol_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; ol_text_shadow_vertical_length_tablet=&#8221;0px&#8221; ol_text_shadow_blur_strength_tablet=&#8221;1px&#8221; quote_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; quote_text_shadow_vertical_length_tablet=&#8221;0px&#8221; quote_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_2_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_2_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_2_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_3_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_3_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_3_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_4_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_4_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_4_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_5_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_5_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_5_text_shadow_blur_strength_tablet=&#8221;1px&#8221; header_6_text_shadow_horizontal_length_tablet=&#8221;0px&#8221; header_6_text_shadow_vertical_length_tablet=&#8221;0px&#8221; header_6_text_shadow_blur_strength_tablet=&#8221;1px&#8221; box_shadow_horizontal_tablet=&#8221;0px&#8221; box_shadow_vertical_tablet=&#8221;0px&#8221; box_shadow_blur_tablet=&#8221;40px&#8221; box_shadow_spread_tablet=&#8221;0px&#8221;]Most of our APIs will deal with database content of course so lets take a look at how we can build these types of APIs.<\/p>\n<p>As a sample database we chose to use DAWs order entry database just because we all have and know it already.<\/p>\n<p>To start with an easy one we will create an API for the inventory table<\/p>\n<p>We will add another HTTP Handler based on the cszWebAPIController class named oInventoryAPI<\/p>\n<pre>Object oInventoryAPI is a cszWebAPIController\n  Set psResourceName to \"Inventory Item\"\n  Set Key_Field to Field inventory.Item_ID\n  Set psPath to \"api\/v1\/inventory\"\n  Set psVerbs to \"*\"\n   ... \nEnd_Object<\/pre>\n<p>we also need to add our DataDictionaries<\/p>\n<pre>Object oVendor_DD is a cVendorDataDictionary \nEnd_Object\n\nObject oInventory_DD is a cInventoryDataDictionary\n\u00a0 \u00a0 Set DDO_Server to oVendor_DD\nEnd_Object\n\nSet Main_DD to oInventory_DD<\/pre>\n<p>then we define the data model as follows<\/p>\n<pre>Procedure OnDefineModels\n  Send BeginModel \"inventory\"\n  Send AddTableColumn File_Field Inventory.Item_ID\n  Send AddTableColumn File_Field Inventory.Description\n  Send AddTableColumn File_Field Inventory.Vendor_ID \n  Send AddTableColumn File_Field Inventory.Vendor_Part_ID\n  Send AddTableColumn File_Field Inventory.Unit_Price\n  Send AddTableColumn File_Field Inventory.On_Hand\n  Send EndModel\nEnd_Procedure<\/pre>\n<p>next we want to define a route to get a list of inventory items<\/p>\n<pre>Send RegisterPath \"GET\" \"\" (RefProc(webAPI_Get))<\/pre>\n<p>this is all that is needed to create a REST API to return a list of inventory items. And again as before the OpenAPI documentation is created automatically as well<\/p>\n<p>now lets see what it takes to add another route to return a single inventory item by id<\/p>\n<p>we need to define a new route as follows<\/p>\n<pre>Send RegisterPath \"GET\" \"\/{itemid}\" (RefProc(webAPI_GetScalar))<\/pre>\n<p>this new route has a variable parameter called itemid. this item id is passed as a variable to the webAPI_GetScalar method which handles finding the record and returning the json object based on the schema provided<\/p>\n<p>Now what about deleting an inventory item<\/p>\n<p>lets add the following route<\/p>\n<pre>Send RegisterPath \"DELETE\" \"\/{itemid}\" (RefProc(webAPI_Delete))<\/pre>\n<p>this route again uses a variable parameter for the item id and passes it to the <em>webAPI_Delete<\/em> method which handles deleting the inventory item.<\/p>\n<p>Now what about creating new inventory records. For this to work we need a POST route as follows<\/p>\n<pre>Send RegisterPath \"POST\" \"\" (RefProc(webAPI_Post))<\/pre>\n<p>this route will use the schema provided as an input from the post method and create an inventory record by calling the <em>webAPI_Post<\/em> method.<\/p>\n<p>Then of course we would like to update an inventory record as well. We can do this by declaring a PATCH route as follows<\/p>\n<pre>Send RegisterPath \"PATCH\" \"\/{itemid}\" (RefProc(webAPI_Patch))<\/pre>\n<p>And this is all that is needed to update inventory records.<\/p>\n<p>And again the documentation for the API is automatically created usign the OpenAPI specifications<\/p>\n<p>the schema we used so far in this example is a pretty simple flat schema. What if we wanted a more complex schema adding a child object for the vendor definition and maybe even a child object for the vendors address even though it only exists in a flat structure in the table.<\/p>\n<p>Also we want some of the fields to only appear in the scalar functions and not in the return of the list methods<\/p>\n<p>lets look at the following schema declaration<\/p>\n<pre>Procedure OnDefineModelColumnsVendorAddress \n  Send AddTableColumn File_Field Vendor.Address \n  Send AddTableColumn File_Field Vendor.City \nEnd_Procedure \n\nProcedure OnDefineModelColumnsVendor \n  Send AddTableColumn File_Field Vendor.ID \n  Send AddTableColumn File_Field Vendor.Name \n  Send AddModelParent \"Address\" (RefProc(OnDefineModelColumnsVendorAddress)) \nEnd_Procedure\n\nProcedure OnDefineModels \n  Send BeginModel \"inventory\" \n  Send AddTableColumn File_Field Inventory.Item_ID \n  Send AddTableColumn File_Field Inventory.Description  \n  Send AddModelParent \"Vendor\" (RefProc(OnDefineModelColumnsVendor)) True \n  Send AddTableColumn File_Field Inventory.Vendor_ID \n  Send AddTableColumn File_Field Vendor.Name \n  Send AddTableColumn File_Field Inventory.Vendor_Part_ID \n  Send AddTableColumn File_Field Inventory.Unit_Price \n  Send AddTableColumn File_Field Inventory.On_Hand \n  Send EndModel \nEnd_Procedure<\/pre>\n<p>we start by defining a schema called inventory with the fields item_id and description<\/p>\n<p>then we add a parent schema called vendor with the vendor fields but we define this parent as scalar only so it will not appear in the return data when getting a list of inventory items.<\/p>\n<p>and here is a quick screen grab of the documentation for the API<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi-1024x985.png\" width=\"1024\" height=\"985\" alt=\"\" class=\"wp-image-810 alignnone size-large\" srcset=\"http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi-1024x985.png 1024w, http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi-300x288.png 300w, http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi-768x739.png 768w, http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi-1080x1039.png 1080w, http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2020\/10\/invapi.png 1850w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>This is just an example there are a number of features to describe the schemas and you can also define multiple schemas to be used for different routes.<\/p>\n<p>In the next part to this series we will look at the order API which will show additional features of the library[\/et_pb_text][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;3.26.7&#8243;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;3.26.7&#8243;][et_pb_text _builder_version=&#8221;3.26.7&#8243;]\n\t\t<div class='author-shortcodes'>\n\t\t\t<div class='author-inner'>\n\t\t\t\t<div class='author-image'>\n\t\t\t<img src='http:\/\/salzlechner.com\/dev\/wp-content\/uploads\/sites\/2\/2016\/02\/mike5crop-566174_60x60.jpg' alt='' \/>\n\t\t\t<div class='author-overlay'><\/div>\n\t\t<\/div> \n\t\t<div class='author-info'>\n\t\t\tMichael Salzlechner is the CEO of StarZen Technologies, Inc.<\/p>\n<p>He was part of the Windows Team at Data Access Worldwide that created the DataFlex for Windows Product before joining\u00a0StarZen Technologies. StarZen Technologies provides consulting services as well as custom Application development and third party products<\/p>\n\t\t<\/div>\n\t\t\t<\/div>\n\t\t<\/div>[\/et_pb_text][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most of our APIs will deal with database content of course so lets take a look at how we can build these types of APIs. As a sample database we chose to use DAWs order entry database just because we all have and know it already. To start with an easy one we will create [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","ngg_post_thumbnail":0,"footnotes":""},"categories":[6,27,1],"tags":[],"class_list":["post-802","post","type-post","status-publish","format-standard","hentry","category-dataflex","category-dataflex-webapp","category-uncategorized"],"_links":{"self":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/comments?post=802"}],"version-history":[{"count":8,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/802\/revisions"}],"predecessor-version":[{"id":829,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/posts\/802\/revisions\/829"}],"wp:attachment":[{"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/media?parent=802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/categories?post=802"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/salzlechner.com\/dev\/wp-json\/wp\/v2\/tags?post=802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}