<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web Service &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/web-service/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 18 Aug 2025 20:38:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Create Fast RESTful APIs in Xojo</title>
		<link>https://blog.xojo.com/2024/10/14/create-fast-restful-apis-in-xojo/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 14 Oct 2024 12:01:31 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API Development]]></category>
		<category><![CDATA[Backend Development]]></category>
		<category><![CDATA[Client-Server Architecture]]></category>
		<category><![CDATA[Data Communication]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Server-Side Programming]]></category>
		<category><![CDATA[Web API]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13881</guid>

					<description><![CDATA[Application programming interfaces (APIs) are essential for enabling digital interactions. They facilitate communication and data sharing between systems, forming the backbone of many applications and&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Application programming interfaces (APIs) are essential for enabling digital interactions. They facilitate communication and data sharing between systems, forming the backbone of many applications and services.</p>



<p>This article examines Xojo&#8217;s capabilities by building a simple web API service. You will learn to handle different HTTP methods, manage requests, and send meaningful responses. Xojo&#8217;s simplicity makes it an excellent choice for experienced developers transitioning from other languages, as well as those familiar with its user-friendly language.</p>



<h3 class="wp-block-heading">Foundation: The HandleURL Function</h3>



<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-ad2f72ca wp-block-group-is-layout-flex">
<p>At the heart of every Xojo-developed web API service is the <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-handleurl" target="_blank" rel="noreferrer noopener">HandleURL</a> function, included in the App class, responsible for handling the request-response cycle. It receives incoming web requests (<a href="https://documentation.xojo.com/api/web/webrequest.html" target="_blank" rel="noreferrer noopener">WebRequest</a>), processes them based on their characteristics, and crafts appropriate responses (<a href="https://documentation.xojo.com/api/web/webresponse.html" target="_blank" rel="noreferrer noopener">WebResponse</a>) to send back.</p>
</div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="286" height="79" src="https://blog.xojo.com/wp-content/uploads/2024/10/image.png" alt="" class="wp-image-13882"/></figure>
</div>


<h3 class="wp-block-heading">Defining API Endpoints for GET Requests</h3>



<p>GET requests are primarily used to retrieve data. To handle these requests effectively, let&#8217;s see how to define API endpoints that correspond to specific data or actions in the following code example:</p>



<pre class="wp-block-code"><code>If request.Method = "GET" Then
  Select Case request.Path
  <strong>Case "time"</strong>
    Var currentTime As String = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
    response.Write("{""message"": """ + currentTime + """}")
    response.Status = 200
    Return True
  <strong>Case "hello"</strong>
    response.Write("{""message"": ""Hello, World!""}")
    response.Status = 200
    Return True
  End Select
End If</code></pre>



<p>Here, we define two endpoints: /time and /hello.</p>



<p>A GET request to /time will return the current date and time in JSON format, while a request to /hello will return a friendly &#8220;Hello, World!&#8221; greeting.</p>



<p>The response.Status is set to 200, indicating a successful response. Learn more here about <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" data-type="link" data-id="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes" target="_blank" rel="noreferrer noopener">HTTP status codes</a>.</p>



<h3 class="wp-block-heading">Defining API Endpoints for POST Requests</h3>



<p>While GET requests primarily retrieve data, POST requests submit data to the API for processing. Consider submitting a form online – you are sending data to the server via a POST request.</p>



<pre class="wp-block-code"><code>If request.Method = "POST" Then
  Select Case request.Path
  <strong>Case "some-data"</strong>
    Try
      Var jReceivedData As New JSONItem(request.Body)
      Response.Write(jReceivedData.ToString)
      Response.Status = 200
      Return True
    Catch e As JSONException
      response.Write("{""error"": ""Internal Server Error""}")
      response.Status = 500
      Return True
    End Try
  End Select
End If</code></pre>



<p>In this example, a POST request to the /some-data endpoint expects to receive JSON data (<a href="https://documentation.xojo.com/api/web/webrequest.html#webrequest-body" target="_blank" rel="noreferrer noopener">request.Body</a>) for processing.</p>



<p>If the data is successfully parsed, the API responds with the received data.</p>



<p>Otherwise, an error status and message are returned to the client.</p>



<h3 class="wp-block-heading">Bringing it all Together</h3>



<p>Now that you know how to manage &#8220;GET&#8221; and &#8220;POST&#8221; requests, you can start building more complex APIs, with different endpoints available for different methods. To further illustrate API endpoint development, consider the following detailed code example that can be used as template:</p>



<pre class="wp-block-code"><code>Function HandleURL(request As WebRequest, response As WebResponse) Handles HandleURL as Boolean
  response.MIMEType = "application/json"
  
  Try
    Select Case request.Method
    Case "GET"
      
      Select Case request.Path
      Case "time"
        Var currentTime As String = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
        response.Write("{""message"": """ + currentTime + """}")
        response.Status = 200
        Return True
      Case "hello"
        response.Write("{""message"": ""Hello, World!""}")
        response.Status = 200
        Return True
      Else
        response.Write("{""error"": ""Not Found""}")
        response.Status = 404
        Return True
      End Select
      
    Case "POST"
      
      Select Case request.Path
      Case "some-data"
        Try
          Var jReceivedData As New JSONItem(request.Body)
          Response.Write(jReceivedData.ToString)
          Response.Status = 200
          Return True
        Catch e As JSONException
          response.Write("{""error"": ""Internal Server Error""}")
          response.Status = 500
          Return True
        End Try
      Else
        response.Write("{""error"": ""Not Found""}")
        response.Status = 404
        Return True
      End Select
      
    End Select
    
  Catch e As RuntimeException
    response.Write("{""error"": ""Internal Server Error""}")
    response.Status = 500
    Return True
  End Try
  
  response.Write("{""error"": ""Not Found""}")
  response.Status = 404
  Return True
  
End Function</code></pre>



<p>Small note: observe the start line within the HandleURL function.</p>



<pre class="wp-block-code"><code>response.MIMEType = "application/json"</code></pre>



<p>This line of code informs the client (browser, application) that the API service is responding using the JSON format. Setting the MIMEType to &#8220;application/json&#8221; is best practice and helps prevent any potential parsing errors on the client side.</p>



<h3 class="wp-block-heading">Next Steps</h3>



<p>You might notice that some code is repeating itself (hint: the error responses), so a good idea would be to create a helper method that deals with this particular type of code repetition. Additionally, consider moving the code from the HandleURL function to a separate method that is then invoked within the HandleURL function for improved organization. This restructuring will enhance code organization, making it easier to maintain, read, and improve the efficiency of the program.</p>



<p>P.S.: You should also check the <a href="https://blog.xojo.com/2024/09/24/microservices-building-modern-scalable-applications/" data-type="link" data-id="https://blog.xojo.com/2024/09/24/microservices-building-modern-scalable-applications/" target="_blank" rel="noreferrer noopener">article about microservices</a> and their purpose to get a better idea of what kind of API interfaces you can create.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Cloud: More Than Web App Hosting</title>
		<link>https://blog.xojo.com/2024/08/15/xojo-cloud-more-than-web-app-hosting/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 15 Aug 2024 22:59:40 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Push Notifications]]></category>
		<category><![CDATA[SFTP]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13449</guid>

					<description><![CDATA[What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>What better way to celebrate 10 years of Xojo Cloud than bragging about all the things it can do! When you think of Xojo Cloud, you might think that it is for hosting Xojo web apps. And that&#8217;s true, Xojo Cloud continues to be the best and easiest way to host your Xojo web apps, but Xojo Cloud also offers several useful services for other types of apps.</p>



<h2 class="wp-block-heading">iOS Notifications</h2>



<p>Xojo Cloud can function as an <a href="https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns">Apple Push Notification system</a> (APNs) for handling iOS push notifications. This works with Xojo and non-Xojo iOS apps. All Xojo Cloud servers are pre-configured to <a href="https://documentation.xojo.com/topics/ios/sending_and_receiving_mobile_notifications.html#topics-ios-creating-notifications-on-the-user-s-mobile-device-using-xojo-cloud-to-send-remote-notifications">send remote notifications</a>. Unlike many other cloud hosts, there is no extra charge for this feature nor is there any limit as to how many notifications you can send.</p>



<p>To send remote notifications from your iOS app you&#8217;ll need to go to the Apple Developer website to do these tasks:</p>



<ol class="wp-block-list">
<li>Add the Push Notifications feature to the App ID.</li>



<li>Generate an Apple Push Services certificate.</li>
</ol>



<p>In Xojo you need to enable the Remote Notifications entitlement for your app in the Capabilities section of the iOS Build Settings Advanced tab.</p>



<p>The final step is to upload your Push Services certificate using the Xojo Cloud control panel.</p>



<p>With super-easy access and no limits for notifications, Xojo Cloud can serve as a great APNs for handling your iOS notification needs.</p>



<h2 class="wp-block-heading">Database Servers</h2>



<p>Most desktop apps use a database of some kind and many are client/server database apps that talk directly to the database server. With Xojo Cloud you can host PostgreSQL or MariaDB/MySQL database servers and connect to them using an SSH tunnel for security purposes.</p>



<p>Setting up a database server on your Xojo Cloud is as easy as checking a box in the control panel.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="630" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png" alt="" class="wp-image-13451" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1024x630.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-300x185.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-768x472.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image.png 1398w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can turn on PostgreSQL or MySQL/MariaDB. If your Xojo Cloud server is large enough you could even do both.</p>



<p>If you want to access a database on Xojo Cloud from a desktop app, you will have to enable the SSH Tunnel and then connect to the tunnel from the computer. An SSH tunnel is a secure connection between your computer and another (in this case your Xojo Cloud server) which is used for transmitting data on a specific port. In essence, it creates a private connection through the internet which allows you to see into your server on the other end and connect to a particular service there.</p>



<p>To create a tunnel between a computer and your Xojo Cloud server, you first need to turn on the tunnel capability on your Xojo Cloud server. Go to your control panel and click the &#8220;SSH Tunnel&#8221; checkbox. You will be presented with a generated username and a password which you will use later for establishing the connection.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="694" height="302" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png" alt="" class="wp-image-13453" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-1.png 694w, https://blog.xojo.com/wp-content/uploads/2024/08/image-1-300x131.png 300w" sizes="(max-width: 694px) 100vw, 694px" /></figure>



<p>On macOS and Linux, you can use a terminal command to access the tunnel (replace username and ipaddress as appropriate; you&#8217;ll be prompted for the password).</p>



<p>Use this command to tunnel to PostgreSQL:</p>



<pre class="wp-block-code"><code>ssh -L 5432:localhost:5432 username@ipaddress -N</code></pre>



<p>Use this command to tunnel to MySQL:</p>



<pre class="wp-block-code"><code>ssh -L 3306:localhost:3306 username@ipaddress -N</code></pre>



<p>If you are using Windows, you will need to use an external app such as PuTTY. There are a number of tutorials available on the internet, just put “putty ssh tunnel” into your favorite search engine.</p>



<p>With the tunnel in place you connect to the database as if it were local to the computer. This works with anything, not just Xojo apps.</p>



<h2 class="wp-block-heading">SFTP</h2>



<p>Xojo Cloud offers SFTP (Secure File Transfer Protocol) for file transfer. SFTP is a secure variant of FTP which transmits files over the internet using strong encryption. That way you don&#8217;t have to worry about anyone intercepting your username and password or your files as they&#8217;re sent to or from your server.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>When choosing a client, keep in mind that SFTP is different than FTPS or FTP w/ SSL. They are not interchangeable with one another.</p>
</blockquote>



<p>Once you enable SFTP in the Control Panel, you&#8217;ll be presented with a dialog showing a generated username and password.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="447" src="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png" alt="" class="wp-image-13454" srcset="https://blog.xojo.com/wp-content/uploads/2024/08/image-2-1024x447.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-300x131.png 300w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2-768x335.png 768w, https://blog.xojo.com/wp-content/uploads/2024/08/image-2.png 1186w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>You can now connect using your favorite SFTP client. If you don&#8217;t have one, there are a number of free and paid options available including:</p>



<ul class="wp-block-list">
<li>ForkLift</li>



<li>Transmit</li>



<li>FileZilla</li>



<li>CyberDuck</li>
</ul>



<p>Having a place to store files online is always handy and can be useful when needing to share files with others without having to rely on services such as DropBox.</p>



<h2 class="wp-block-heading">Web Services</h2>



<p>OK, a web service is technically a Xojo web app but it is really an API that is meant to be used by other apps, often desktop or mobile apps. Since a web service doesn’t have any actual UI, you don’t really need to learn how to use the majority of the Xojo Web framework.</p>



<p>Instead you basically add code to the <a href="https://documentation.xojo.com/api/web/webapplication.html#webapplication-handleurl">App.HandleURL</a> event to route web service API calls to do specific tasks and then return the results, usually as JSON for the client app to handle.</p>



<p>A web service can be a great way to consolidate code that will be used by desktop and mobile apps, for example.</p>



<p>For example, you could create a Web Service that talks to a database server (such as one of the ones available in Xojo Cloud itself). Your Desktop and Mobile apps can use the same web service to work with the database. All your database-specific code lives in the web service and the client apps make requests and display results.</p>



<p>This is a very common design pattern these days and is a necessary one if you want a mobile app to talk to a database server.</p>



<p>If you want to learn more about web services, here&#8217;s a fun webinar to check out:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="Using Xojo and the Star Wars API" width="500" height="281" src="https://www.youtube.com/embed/hwhkZtP6fA8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Learn more about <a href="https://xojo.com/cloud/">Xojo Cloud</a> today. Xojo Cloud servers start at $49/month, custom servers with more RAM, storage, and virtual CPUs are available. The best way to host your Xojo web apps is so much more than just hosting web apps!</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Testing REST-based Web Services</title>
		<link>https://blog.xojo.com/2023/03/07/testing-rest-based-web-services/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Tue, 07 Mar 2023 15:16:55 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[URLConnection]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11358</guid>

					<description><![CDATA[Using Xojo's URLConnection to communicate with web services is pretty straightforward. But testing the actual REST API calls can get tricky. To make it easier to test and experiment with REST API calls, Paul created a app in Xojo that lets you test REST APIs. He called it RESTy in its original format back in 2015. You can download the updated project here built with Xojo 2022r4.1.]]></description>
										<content:encoded><![CDATA[
<p>Using Xojo&#8217;s URLConnection to communicate with web services is pretty straightforward. But testing the actual REST API calls can get tricky. To make it easier to test and experiment with REST API calls, Paul created an app in Xojo for doing just this. He called it RESTy in its original format back in 2015. The most recent version of the example project can be found in Xojo by choosing File > New Project, clicking on Examples then clicking on Communication > Internet > Web Services >RESTy.</p>



<span id="more-11358"></span>



<p>RESTy uses the <a href="https://documentation.xojo.com/api/networking/urlconnection.html#urlconnection">URLConnection</a> class to send a request to a web service and get a result. If the result is text (JSON, for example)&nbsp;it displays in the <strong>Response</strong> tab. Here, I am calling the <a href="https://documentation.xojo.com/topics/communication/internet/testing_a_web_service.html">Eddie&#8217;s Electronics web service</a> to return a list of all the customers by specifying the URL and clicking the Fetch button:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="965" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/03/getallcustomers-965x1024.png" alt="" class="wp-image-11365" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/getallcustomers-965x1024.png 965w, https://blog.xojo.com/wp-content/uploads/2023/03/getallcustomers-283x300.png 283w, https://blog.xojo.com/wp-content/uploads/2023/03/getallcustomers-768x815.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/getallcustomers.png 1200w" sizes="auto, (max-width: 965px) 100vw, 965px" /></figure>



<p>For other data (binary data such as pictures) you can use the Fetch to File button to save the request to a file.</p>



<p>The Authentication tab is used to provide Basic Authentication should the web service require it.</p>



<p>The Request Content tab can be used to provide Content data that the request might need. For example, the Eddie&#8217;s Electronics web service also lets you request the details for a specific customer by providing simple JSON containing the customer ID. To try this using RESTy app:</p>



<ol class="wp-block-list">
<li>Click on the Request Content Tab.</li>



<li>To indicate the customer you wish to retrieve, enter the following JSON into the field on that tab: <code>{"ID": 10039}</code></li>



<li>Select <strong>POST</strong> from the Send Method popup menu.</li>



<li>In the URL field, enter: <code>https://eews-demos.xojo.com/GetCustomer</code></li>



<li>Press the Fetch button.</li>
</ol>



<p>If you have entered everything correctly, will see the data for Caleb Horn in JSON format:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="965" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/03/getonecustomer-1-965x1024.png" alt="" class="wp-image-11367" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/getonecustomer-1-965x1024.png 965w, https://blog.xojo.com/wp-content/uploads/2023/03/getonecustomer-1-283x300.png 283w, https://blog.xojo.com/wp-content/uploads/2023/03/getonecustomer-1-768x815.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/getonecustomer-1.png 1200w" sizes="auto, (max-width: 965px) 100vw, 965px" /></figure>



<p>And to see the JSON formatted nicely, click the Format JSON button:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="965" height="1024" src="https://blog.xojo.com/wp-content/uploads/2023/03/formattedJSON-965x1024.png" alt="" class="wp-image-11368" srcset="https://blog.xojo.com/wp-content/uploads/2023/03/formattedJSON-965x1024.png 965w, https://blog.xojo.com/wp-content/uploads/2023/03/formattedJSON-283x300.png 283w, https://blog.xojo.com/wp-content/uploads/2023/03/formattedJSON-768x815.png 768w, https://blog.xojo.com/wp-content/uploads/2023/03/formattedJSON.png 1200w" sizes="auto, (max-width: 965px) 100vw, 965px" /></figure>



<p>This will let you you explore calling various REST API services. You can explore the source code to see how it uses URLConnection to do so.</p>



<p>To be sure, RESTy is very basic, but you have the source code so you and add features to it and modify it for your own testing needs.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Guest Post: Adding Language Translation to Your Xojo Apps</title>
		<link>https://blog.xojo.com/2019/05/13/guest-post-adding-language-translation-to-your-xojo-apps/</link>
		
		<dc:creator><![CDATA[Tim Dietrich]]></dc:creator>
		<pubDate>Mon, 13 May 2019 10:00:17 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[App Localization]]></category>
		<category><![CDATA[CURL]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Monkeybread Software]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Translation]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5735</guid>

					<description><![CDATA[I've been amazed at the speed and accuracy of the Amazon Translate service. And after developing the AWSTranslator class, I was able to quickly and easily add language translation to my client's middleware app.]]></description>
										<content:encoded><![CDATA[<p>Recently, I was asked by a client if it would be possible to build language translation functionality into a Xojo-based middleware solution that I had developed for them. The Xojo app obtains product information (including product names, descriptions, and other marketing-related information) from suppliers via a SOAP call, and returns the data in a JSON-encoded response. They wanted to be able to translate the product information, which is provided in English, to other languages (such as French, German, etc). The client wanted something similar to <a href="https://translate.google.com/">Google Translate</a>. However, they wanted the translation function to be built directly into the app and to be performed &#8220;on demand.&#8221;</p>
<p>I did some research and found that Amazon provides a service that does exactly what the client was asking for. The service, called <a href="https://aws.amazon.com/translate/">Amazon Translate</a>, is available as one of many services that are available through Amazon Web Services.</p>
<p>In this post, I&#8217;ll walk you through the process of getting signed up for Amazon Translate, and then share some code that you can use to add language translation to your own Xojo projects. We&#8217;ll use the MBS Xojo CURL Plugin, which makes calling the Amazon Translate API easy. But first, let&#8217;s learn a little about Amazon Translate.</p>
<p><span id="more-5735"></span></p>
<h3><b>Amazon Translate</b></h3>
<p>Amazon Translate is an API that can be used to translate text on demand. You send it text in a &#8220;source language,&#8221; tell the API what that source language is, as well as the &#8220;target language&#8221; that you want the text translated to. The API responds with the translated text.</p>
<p>Amazon Translate uses machine learning and neural networks that have been designed specifically for language translation. When performing a translation, the service reads the text one sentence at a time, and reads each word individually, to determine the meaning of a sentence. In other words, the service doesn&#8217;t just translate words. Instead, it&#8217;s acting as an interpreter. This results in translations that are extremely accurate.</p>
<p>In order to use Amazon Translate, you&#8217;ll need an <a href="http://aws.amazon.com/">AWS account</a>. If you already have an AWS account, log into the account.</p>
<p>Next, you&#8217;ll need to create an &#8220;Identity and Access Management&#8221; (IAM) user. To do so, under Services, select &#8220;IAM&#8221; (which can be found in the &#8220;Security, Identity, &amp; Compliance&#8221; category). This will present you with the IAM Dashboard.</p>
<p>Under Groups, create a new group and give it a recognizable name. For example, you might call the group &#8220;translate.&#8221; As you are creating the group, give it the &#8220;TranslateFullAccess&#8221; permission.</p>
<p>Next, create an IAM user. Under Users, click the &#8220;Add user&#8221; button. Give the user a name such as &#8220;XojoTranslater.&#8221; For the &#8220;AWS access type&#8221; be sure to select &#8220;Programmatic access.&#8221; Add the user to the &#8220;translate&#8221; group that you created above. There&#8217;s no need to assign any tags to the user, so you can skip that step.</p>
<p>And finally, create an Access key for the user. Be sure to make note of both the &#8220;Access key ID&#8221; and &#8220;Secret access key&#8221; values that are automatically assigned. You&#8217;ll need these in order to make API calls.</p>
<h3><b>The MBS Xojo CURL Plugin</b></h3>
<p>If you don&#8217;t already have the <a href="https://www.monkeybreadsoftware.de/xojo/plugin-curl.shtml">MBS Xojo CURL Plugin</a>, download it and install it. To install the plugin, simply drag it into the Xojo &#8220;Plugins&#8221; folder.</p>
<p>The project will work with an unlicensed version of the MBS Xojo CURL Plugin. In this case, you&#8217;ll occasionally see a popup message reminding you to purchase a license. However, I highly encourage you to purchase a license. You can license the plugin individually, or as part of the MBS Complete plugin bundle.</p>
<h3><b>The Xojo Example Project</b></h3>
<p>To demonstrate the Amazon Translate service, I&#8217;ve put together an example Xojo desktop project (<a href="https://s3.amazonaws.com/tdietrich-opensource/aws-translate-demo.xojo_binary_project.zip">project file</a>). Before running the application, be sure to set the three App-level properties: AWSAccessKeyId, AWSSecretAccessKey, and the AWSRegion. For the AWSAccessKeyId and AWSSecretAccessKey properties, use the values that you set when you created the Access key for the user. For the AWSRegion, refer to <a href="https://docs.aws.amazon.com/general/latest/gr/rande.html">this</a> and use the value that makes the most sense for you.</p>
<p>Once you&#8217;ve configured the app, run it, and it will look something like this.</p>
<p> </p>
<h3><b>The Xojo Code</b></h3>
<p>Let&#8217;s take a look at some of the code.</p>
<p>The AWSTranslator class is a subclass of the CURLSMBS class. The class does two important things: It provides access to a list of the languages that are supported, and provides a method for calling the Amazon Translate API.</p>
<p>The &#8220;Languages&#8221; property is a dictionary that you can use to get the names of the languages that Amazon Translate supports and the corresponding language codes. The example app uses this dictionary to populate the &#8220;Translate From&#8221; (SourcePopupMenu) and &#8220;Translate To&#8221; (TargetPopupMenu) popup menus.</p>
<p>The Translate method creates the payload that gets sent to the Amazon Translate API, and sets special HTTP headers that are needed in order to call the API. But most importantly, it uses the CURLSMBS class&#8217;s &#8220;SetupAWS&#8221; method to configure the CURL instance so that all of the steps that are required to &#8220;sign&#8221; the API request are done automatically. This is an amazingly convenient function of the MBS Xojo CURL Plugin. You can get a sense of what&#8217;s involved in signing the request <a href="https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html">here</a>.</p>
<p>To translate text using the AWSTranslator class, you create an instance, configure it with your IAM credentials and AWS region, pass it the source language text, the source language code, and the target language code. In the example app, this all handled in the Window1.Translate method. The values are pulled from the App-level properties, as well as the various window controls. Finally, you call the AWSTranslator instance&#8217;s Translate method. If the translation is successful, the translated text will be available via the TranslatedText property. If any errors occur, the ErrorType and ErrorMessage properties will be set.</p>
<p>The &#8220;Estimated Translation Cost&#8221; is calculated whenever the Source Text changes. The value is calculated by taking the length (number of characters) of the Source Text and multiplying it by 0.000015 (the average cost for translating a single character).</p>
<h3><b>Wrapping Up</b></h3>
<p>I&#8217;ve been amazed at the speed and accuracy of the Amazon Translate service. And after developing the AWSTranslator class, I was able to quickly and easily add language translation to my client&#8217;s middleware app.</p>
<p>I hope you&#8217;re equally impressed by the Amazon Translate service, and that you find the AWSTranslator class to be helpful in your own Xojo projects.</p>
<p><i>Tim Dietrich is a custom software developer based in Richmond, Virginia. To learn more, visit: <a href="https://timdietrich.me/" target="_blank" rel="noopener noreferrer" data-saferedirecturl="https://www.google.com/url?q=https://timdietrich.me&amp;source=gmail&amp;ust=1552488320387000&amp;usg=AFQjCNEDiwUxo_XLnpKX-Bt3nL8FIQTxZA">https://timdietrich.me</a></i></p>


<figure class="wp-block-image"><img loading="lazy" decoding="async" width="1024" height="711" src="https://blog.xojo.com/wp-content/uploads/2019/05/Screen-Shot-2019-04-01-at-4.21.01-PM-1024x711.png" alt="" class="wp-image-5753" srcset="https://blog.xojo.com/wp-content/uploads/2019/05/Screen-Shot-2019-04-01-at-4.21.01-PM-1024x711.png 1024w, https://blog.xojo.com/wp-content/uploads/2019/05/Screen-Shot-2019-04-01-at-4.21.01-PM-300x208.png 300w, https://blog.xojo.com/wp-content/uploads/2019/05/Screen-Shot-2019-04-01-at-4.21.01-PM-768x533.png 768w, https://blog.xojo.com/wp-content/uploads/2019/05/Screen-Shot-2019-04-01-at-4.21.01-PM.png 1532w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite is not a server</title>
		<link>https://blog.xojo.com/2019/01/10/sqlite-is-not-a-server/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 10 Jan 2019 10:00:54 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5299</guid>

					<description><![CDATA[If you are using SQLite you might be trying to share your database. What are your options when you want to be able to share your database?  ]]></description>
										<content:encoded><![CDATA[<p>People often ask about a way to share a <a href="http://www.sqlite.org">SQLite</a> database across multiple apps. Essentially they want to know how to use SQLite as a server and the most common questions relate to putting a SQLite database file on a shared network drive and accessing the database file from apps running on multiple computers. This is a really bad idea, as even the SQLite folks will tell you. I&#8217;ll quote the relevant section from their &#8220;<a href="https://www.sqlite.org/whentouse.html">When to use SQLite</a>&#8221; page:</p>
<blockquote><p><strong>Situations Where A Client/Server RDBMS May Work Better</strong></p>
<p><strong>Client/Server Applications</strong></p>
<p>If there are many client programs sending SQL to the same database over a network, then use a client/server database engine instead of SQLite. SQLite will work over a network filesystem, but because of the latency associated with most network filesystems, performance will not be great. Also, file locking logic is buggy in many network filesystem implementations (on both Unix and Windows). If file locking does not work correctly, two or more clients might try to modify the same part of the same database at the same time, resulting in corruption. Because this problem results from bugs in the underlying filesystem implementation, there is nothing SQLite can do to prevent it.</p>
<p>A good rule of thumb is to avoid using SQLite in situations where the same database will be accessed directly (without an intervening application server) and simultaneously from many computers over a network.</p></blockquote>
<p>So what are your options when you want to share your database?</p>
<p>If you want to stick with SQLite then you&#8217;ll need to put something in front of it that can handle requests from multiple client apps. The most obvious solution is to create a web service by using a web app with WebApplication.HandleURL (or HandleSpecialURL). The web app can accept requests from multiple client apps (or any type &#8212; desktop, web, mobile, etc.), fetch the data requested from the SQLite database and then send it back as JSON. This works because the web app is the only app that is connected to the SQLite database.</p>
<p>The <a href="https://documentation.xojo.com/UserGuide:Eddie%27s_Electronics_Sample_Web_Service">Eddie&#8217;s Electronics Web Service sample</a> shows you how you might set this up: Examples/Communication/Web Services/EddiesWebService</p>
<p>Another option for setting up your own database web service is to use the <a href="https://aloe.zone">Aloe open-source project</a>, which gives you a robust framework for building web services.</p>
<p>To learn more about database web services, check out the <a href="https://youtu.be/X58zSmm2iSE">Making Database Web Services video</a>.</p>
<p>By the way, this is also why a regular web app can safely use SQLite with multiple users &#8212; the web app manages the multiple users but is the only app that is connected to the SQLite database.</p>
<p>If you want to stick with SQLite but would rather not create a web service, another option to consider is to use a product that puts a database server around SQLite. <a href="https://www.sqlabs.com/cubesql.php">CubeSQL</a> and <a href="https://www.valentina-db.com/en/sqlite-database-server">Valentina</a> have products available that can do this.</p>
<p>Your final option is to switch to an actual database server. PostgreSQL and MySQL are popular alternatives.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Web Services Part II: Xojo Web, at your service</title>
		<link>https://blog.xojo.com/2018/11/08/web-services-part-ii-xojo-web-at-your-service/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 08 Nov 2018 10:00:10 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[HTTPSocket]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5118</guid>

					<description><![CDATA[In a previous entry we started to dig into web services with Xojo. The first post focused on the backend (server side), creating the Xojo&#8230;]]></description>
										<content:encoded><![CDATA[<p>In a <a href="https://blog.xojo.com/2018/09/26/web-services-xojo-web-at-your-service/">previous entry</a> we started to dig into web services with Xojo. The first post focused on the backend (server side), creating the Xojo app acting as middleware between the clients and the database that holds your data. We are using SQLite as the backend engine but it would not be difficult to change to other supported database engines like PostgreSQL, MySQL (MariaDB), Oracle or SQL Server, and even ODBC; all of these are supported by Xojo!<span id="more-5118"></span></p>
<p>In this second post on the topic we will focus on the client side desktop app that will be in charge of creating the requests using the web service published API. This desktop app will send new data to our web server app so it can be added to the backend database.</p>
<p>The main topics are:</p>
<ul>
<li>Creating a subclass from the <code>URLConnection</code> class</li>
<li>Dealing with the data received from the server as result for the request</li>
<li>Encoding a <code>JSONItem</code> for sending data to the web service</li>
</ul>
<p>As stated in the previous entry, the example doesn&#8217;t include the normal (and recommended) verifications on the data provided and received or the check on possible errors; we are only focused on the main topic.</p>
<h2>Creating an URLConnection subclass</h2>
<p>Let&#8217;s start by creating a new desktop project. Add a new Class using <code>Insert &gt; Class</code> and use the Inspector to assign <code>URLConnection</code> as the <b>Super Data Type</b> as shown in the picture:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-11609 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/11/URLConnectionSubclass.png" alt="" width="602" height="300" srcset="https://blog.xojo.com/wp-content/uploads/2018/11/URLConnectionSubclass.png 602w, https://blog.xojo.com/wp-content/uploads/2018/11/URLConnectionSubclass-300x150.png 300w" sizes="auto, (max-width: 602px) 100vw, 602px" /></p>
<p>With the just added class still selected in the Navigator (the leftmost column in the IDE Window), add a new property to it (<code>Insert &gt; Property</code>). We will use this property so it points to a DesktopListBox in our user interface, and so we can update it with the data received from our web service. With the just added property still selected, use the Inspector to set its Data Type and Name (text label used from our code to refer to such property) as follows:</p>
<ul>
<li><b>Name</b>: List</li>
<li><b>Type</b>: DesktopListBox</li>
<li><b>Scope</b>: Private</li>
</ul>
<p>Note that we set the scope as <b>Private</b>. This means that this property can be accessed only from the instances of the class, and not those that are created from other data types or even those created as subclasses from this class.</p>
<h2>URLConnection: Asynchronous communications</h2>
<p>Why would we want to maintain a reference to a ListBox control in our URLConnection class? As with any kind of problem, we can take several approaches in order to solve it. In this case, is a very convenient way to get a reference to the control we want to update as we will be using the URLConnection asynchronously.</p>
<p>Once we call the request against our web service, the execution of the app will not be paused until we receive a response, this allows the user to do other operations if they want. In this case the class instance, via the <code>ContentReceived</code> event, will be responsible to receive the new data from the web service, so we can use it.</p>
<p>In fact, this is our next step. With our <code>URLConnection</code> subclass still selected in the Navigator, add a new Event Handler to it (<code>Insert &gt; Event Handler…</code>). In the resulting window, choose the <code>PageReceived</code> option from the list and confirm the selection, so the event will be added to the class under the <b>Event Handlers</b> section.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-11610 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/11/URLConnection-ContentReceived-1024x563.png" alt="" width="1024" height="563" srcset="https://blog.xojo.com/wp-content/uploads/2018/11/URLConnection-ContentReceived-1024x563.png 1024w, https://blog.xojo.com/wp-content/uploads/2018/11/URLConnection-ContentReceived-300x165.png 300w, https://blog.xojo.com/wp-content/uploads/2018/11/URLConnection-ContentReceived-768x423.png 768w, https://blog.xojo.com/wp-content/uploads/2018/11/URLConnection-ContentReceived.png 1236w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>Now, with the just added Event Handler still selected, write the following snippet of code in the associated Code Editor:</p>
<pre>#Pragma Unused url

If HTTPStatus = 200 Then // We received an OK as the status for our request
  If Content.Length &lt;&gt; 0 Then // And we have data to process as part of the reply
    List.RemoveAllRows // So we delete previous existing entries in the associated ListBox Control
    content = content.DefineEncoding(Encodings.UTF8) // We set the encoding for the received data
    
    Var items As Dictionary = ParseJSON(content) // And proceed to create a new dictionary from the received data in JSON format
    items = items.Value("AllAlbums") // We get all the items for the key 'AllAlbums'…
    For Each item As DictionaryEntry In items // …iterating on them…
      Dim tempDict As Dictionary = item.Value // …and retrieving the dictionary (JSON item) for it…
      Dim title As String = tempDict.Value("title") // …so we finally access the desired value
      list.AddRow title
    Next
  End If
End If</pre>
<p>The code is commented so you can follow what happens in each line in the process; but it is worth it to point out that the <code>ContentReceived</code> event gives us all the parameters we need in order to work with the data sent from the web service:</p>
<ul>
<li><b>URL</b>: The URL returned as the reply for our request</li>
<li><b>HTTPStatus</b>: The HTTP status code that you <b>should</b> read to verify the success of the request</li>
<li><b>Content</b>: This is a String that can contain the data associated with the reply.</li>
</ul>
<p>In addition, you can also add an extra event handler to our subclass: <code>Error</code>. This will be fired when an error is produced while dealing with requests sent from the instance.</p>
<p>With the events and property already set, it is time to add a couple of methods in charge of commanding our URLConnection subclass to launch the requests. For our example, those method names are directly related to the operations we want to do on the web service API created on the first part of this tutorial.</p>
<p>So, with our URLConnection class still selected in the Navigator, add a new method (<code>Insert &gt; Method</code>), using the following data in the associated Inspector. This is the method in charge of requesting our web service for the name of all the available albums. Of course, we expect to receive the reply through the <code>ContentReceived</code> event:</p>
<ul>
<li><b>Method Name</b>: GetRequest</li>
<li><b>Parameters</b>: theList As DesktopListBox, theURL as String</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>As you can see, this method expects to receive the reference to a <b>DesktopoListBox</b> control, and the text to the URL that should be the end point of our web service. Now put the following code in the associated Code Editor for the just added Method:</p>
<pre>List = theList
self.send("GET", theURL)</pre>
<p>Simple, isn&#8217;t? As you can see, we save the reference to the DesktopListBox control in the instance property so we can use it later for updating its contents with the received data. Then we use the <code>Send</code> method from the class with the <code>GET</code> verb and the URL where our web service should be listening for incoming requests. As previously stated, this is an async operation, so we will let our object to react through the <code>ContentReceived</code> or <code>Error</code> events.</p>
<h2>URLConnection: Sending data as part of a request</h2>
<p>Add a new method to the subclass, using the following values in the resulting Inspector. This is the method allowing us to send data to the web service so they can be added to the backend database:</p>
<ul>
<li><b>Method Name</b>: SendItem</li>
<li><b>Parameters</b>: Item As JSONItem, theURL As String</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>This time, the method expects to receive and JSONItem object (pointed via the variable <code>Item)</code> and a String instance that should be the web service endpoint URL. Put the following code in the associated Code Editor for the method:</p>
<pre>Self.SetRequestContent( item.ToString, "application/json" )
self.Send("POST", theURL)</pre>
<p>The URLConnection instances allow us to associate additional information (data) for a request sending, in addition to those added through the HTTP headers (<code>Head</code>), using for that the <code>SetRequestContent</code> method. This method expects two parameters: a String with the real data to attach, and the definition of the type of data we are sending (this is, the <b>MIME</b> Type) as a String instance.</p>
<p>Finally, we launch the request in the second line of code, using for that the URL assigned to the <code>theURL</code> parameter and using the verb <code>POST</code>.</p>
<h2>Designing the User Interface</h2>
<p>We have already finished all the logic behind our example app, via our URLConnection subclass. So now it&#8217;s time to design a minimal user interface so we can verify the correct functionality of our client agains the web service.</p>
<p>Select the <code>Window1</code> object and add the required control so it looks like the one displayed here (from top to bottom): a DesktopListBox, a couple of DesktopTextFields in addition of two DesktopLabels, and two DesktopPushButtons named &#8220;Request&#8221; and &#8220;Send&#8221;.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-11611 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/11/DesktopWebServiceTest-1024x744.png" alt="" width="1024" height="744" srcset="https://blog.xojo.com/wp-content/uploads/2018/11/DesktopWebServiceTest-1024x744.png 1024w, https://blog.xojo.com/wp-content/uploads/2018/11/DesktopWebServiceTest-300x218.png 300w, https://blog.xojo.com/wp-content/uploads/2018/11/DesktopWebServiceTest-768x558.png 768w, https://blog.xojo.com/wp-content/uploads/2018/11/DesktopWebServiceTest.png 1382w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>Next, add an instance of the created URLConnection subclass. For that, simply drag the created subclass from the Project Browser to the Window Layout Editor and a new instance will be added to the Tray in the lower section of the Editor, as shown in the following picture:</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-11612 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/11/MyConnection.png" alt="" width="596" height="272" srcset="https://blog.xojo.com/wp-content/uploads/2018/11/MyConnection.png 596w, https://blog.xojo.com/wp-content/uploads/2018/11/MyConnection-300x137.png 300w" sizes="auto, (max-width: 596px) 100vw, 596px" /></p>
<p>The only code present in the user interface is the one that we will add to both PushButtons. Double click the one labeled &#8220;Request&#8221;, and add the following line of code to its <code>Pressed</code> Event Handler:</p>
<p><code>MyConnection1.getRequest(AlbumListbox, "http://127.0.0.1:8081/GetAll")</code></p>
<p>It calls the <code>getRequest</code> method on the instance based on our subclass, sending as parameters the control &#8220;ListBox1&#8221; and the text for the (local) URL where the web service should be listening.</p>
<p>Double click the PushButton labeled &#8220;Send&#8221; in order to add the <code>Pressed</code> Event Handler and write the following fragment of code into the associated Code Editor:</p>
<pre>Var d As New Dictionary
d.Value("Title") = TitleField.Text
d.value("ArtistId") = ArtistIDField.Text
Var item As New JSONItem
item.Value("newAlbum") = d

MyConnection1.sendItem(item,"http://127.0.0.1:8081/AddAlbum")</pre>
<p>As you can see, there is nothing magic in it. We simply create a new dictionary using the keys expected from our web server to access the underlaying data for the record. In addition, you can see how easy it is to create a new JSONItem from a Dictionary!</p>
<p>Then, we simply call the <code>sendItem</code> method on our URLConnection subclass instance, passing along the expected parameters: a JSONItem instance and the web service endpoint URL that should include the method we want to call in the remote API.</p>
<h2>Ready to listen for your requests!</h2>
<p>We have finished our client app! Launch the web service created in the first part of the tutorial (make sure it is listening using the port 8081). Then, run the desktop client app and push the buttons for &#8220;sending&#8221; or &#8220;requesting&#8221; the information. You will see how with the request you&#8217;ll receive all the albums available in the example database, while with the &#8220;Send&#8221; button you&#8217;ll be able to add new records to the database with the data provided in both TextFields.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-11613 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/11/AppRunning-1024x777.png" alt="" width="1024" height="777" srcset="https://blog.xojo.com/wp-content/uploads/2018/11/AppRunning-1024x777.png 1024w, https://blog.xojo.com/wp-content/uploads/2018/11/AppRunning-300x228.png 300w, https://blog.xojo.com/wp-content/uploads/2018/11/AppRunning-768x582.png 768w, https://blog.xojo.com/wp-content/uploads/2018/11/AppRunning.png 1424w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></p>
<p>In conclusion, Xojo allows us to create both the backend and the multiplatform clients in record time and in a really easy way! Obviously, the examples used in these two articles are not, by far, complete solutions you can use &#8220;As Is&#8221;, but they give the basics you can use to construct more robust and complete solutions for your own needs.</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
<p>*<a href="https://www.aprendexojo.com/2016/06/crear-servicio-web-con-xojo-parte-ii/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Web Services: Xojo Web, at your service</title>
		<link>https://blog.xojo.com/2018/09/26/web-services-xojo-web-at-your-service/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 26 Sep 2018 10:00:59 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Middleware]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4950</guid>

					<description><![CDATA[In this two part tutorial we will see how easy it is to create a basic web service using Xojo Web. In the second part, we will create a Desktop client to talk with the web service (you may want to add iOS to the list).]]></description>
										<content:encoded><![CDATA[<p>Using Xojo Web to create complete web apps and solutions means not having to learn a bunch of interpreted languages and dozens of ever-changing frameworks. I&#8217;m looking at you: HTML, CSS (is that even a language?), JavaScript, PHP, et al. Of course, <a href="http://xojo.com/products/web.php">Xojo Web</a> not only makes it possible to create your own web apps, but it also acts as the perfect middleware that your desktop and iOS apps can communicate with. Learn about <strong>APIs</strong> and web services with Xojo in the tutorial blog post.<span id="more-4950"></span></p>
<p>In this two part tutorial you will see how easy it is to create a basic web service using Xojo Web. In the second part, we will create a Desktop client to talk with the web service (you may want to add iOS to the list).</p>
<p>Before we start, let me point out that this tutorial leaves out some details related to error checking, validation, data sanitizing and other specifics related to inputs and outputs in order to focus on the central topic. In addition, if you want to follow and reproduce the steps of this tutorial, then you need to download the <a href="https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite">Chinook Database, </a>named &#8220;test.sqlite&#8221; in this tutorial.</p>
<h2>Services in practice</h2>
<p>Let&#8217;s start creating a web service! Open the Xojo IDE, create a new <b>Web project</b>, and name it <code>WebService</code>. The first thing you&#8217;ll notice is that Xojo adds a web page to the project by default &#8211; even when our web service does not display a UI. The good part is that you can mix both worlds, adding the webservice part to your regular Web app!.</p>
<p>In fact this tutorial will put all the logic in the App object. Start by adding a new <b>property</b> in charge of the reference to our <b>SQLite</b> database (of course, it will work also with <b>PostgreSQL</b> or <b>MySQL</b> engines). Select the <code>App</code> object from the <b>Navigator</b> (the left panel in the Xojo IDE), choosing the <code>Insert &gt; Property</code> option from the contextual menu. With the new property selected, go to the <b>Inspector</b> to set the name, type and scope using these values:</p>
<ul>
<li><b>Name: </b>Database</li>
<li><b>Type: </b>SQLiteDatabase</li>
<li><b>Scope: </b>Private</li>
</ul>
<p>Next, we will add the Chinook Database to the Resources folder of our Web App. For that, select the deployment target under Build Settings (it can be macOS, Windows, Linux or Xojo Cloud, for example), and add a Copy Files build step to it. In the resulting Editor, add the Chinook database SQLite file and make sure you select the &#8220;Resources Folder&#8221; entry in the Destination popup menu, and the &#8220;Both&#8221; entry in the Applies To popup menu.</p>
<p>Now is time to create a new SQLiteDatabase instance and assign it to this property, so it will point to the SQLite database file when the app is running. For that, make sure the <code>App</code> object is selected and add the <code>Opening</code> <b>Event Handler</b> to it using the <code>Insert &gt; Event</code> option. Write the following code in the resulting <b>Code Editor</b>:</p>
<pre>#Pragma Unused args

Var f As FolderItem = SpecialFolder.Resource("Chinook_Sqlite.sqlite")

If f.Exists Then
  
  Try
    database = New SQLiteDatabase
    database.DatabaseFile = f
    
    Call database.Connect
  Catch e As DatabaseException
    MessageBox "Error connecting to the database"
  End Try
  
End If</pre>
<p>As you can see, it is pretty much the same code we already use when creating <b>SQLiteDatabase</b> instances in our Desktop apps, <em>linking</em> to our SQLite database file and stablishing the connection so we can operate with the database engine from our app.</p>
<h2>All the Magic of HandleURL</h2>
<p>Xojo Web projects offer a simple way to handle the request received. It is using the <code>HandleURL</code> event. This is the one that fires every time a client app (it may be a Web Browser, desktop or mobile app) connects to the URL associated with the <b>IP address and port combination</b> that is <em>listening</em> for incoming requests.</p>
<p>For example, a valid URL that can be <b>trapped</b> and processed by <code>HandleURL</code> is:</p>
<pre>http://www.nice-web-domain.com/getCustomers</pre>
<p>Where <code>getCustomers</code> is in this case one of our API methods.</p>
<p>So, with the <code>App</code> object selectd, choose <code>Insert &gt; Event</code> in order to add the <code>HandleURL</code> event.</p>
<p>As we will see, once the event has been added to a web app, it will receive the <code>Request</code> parameter (a <code>WebRequest</code> data type), waiting from us to send back a <code>Boolean</code> value as response: <code>True</code> to process the request or <code>False</code> (the default value) to ignore the response.</p>
<h2>Introducing Request, where the information lives!</h2>
<p>In fact, we will find in the <code>Request</code> object everything we need to process and (if it is the case) respond to the request from our Web service. For example, through we can get the interesting component from the <code>Path</code> property. If we consider this URL:</p>
<p><code>http://www.nice-web-domain.com/getCustomers?spain</code></p>
<p>The <code>Request.Path</code> property will return the <code>getCustomers</code> string; so our web service can process it acordingly from this point on.</p>
<h2>Receiving and Sending JSON data</h2>
<p>In order to keep this tutorial brief, our web API only has two methods in it: <code>GetAll</code> and <code>AddAlbum</code>. Using the first one, the client app will get the album name in the database wrapped in JSON format. With the second method, our client app will ask the web service to add a new record (a new album) to the right table on our example database.</p>
<p>How can we process the request associated data inside the <code>HandleURL</code> event? Here is where we will find very useful another of the <code>Request</code> object properties. The <code>Body</code> property includes the sent data as part of the request that are not already present in the headers. Generally speaking, it includes additional data via the <b>PUT</b> and <b>POST</b> verbs.</p>
<p>Now we can put the following code into our <code>HandleURL</code> Event Handler:</p>
<pre>Select Case Request.Path // What is the method received as part of the request? (URL)
Case "GetAll"
  Var output As JSONItem = GetAllAlbums // Assign the processed data to the output variable, if the received method is 'GetAllAlbums'
  
  Response.Header("charset") = "utf-8"
  Response.MIMEType = "application/json"
  Response.Status = 200
  response.write( output.ToString ) // And send it back to the client that made the request, converting the JSON to a String in first place
  
Case "AddAlbum"
  Var data As String = Request.Body.DefineEncoding(encodings.UTF8) // We have to apply the right encoding to the received data
  Var Input As JSONItem = New JSONItem( data ) // Creating a new JSON object from it
  addNewAlbum( Input.Value("newAlbum") ) // In this case, the request is to add a new Album to the database; passing thus the received data as part of the input
End Select

Return True</pre>
<p>The main point here is that we assign the received data to the <code>data</code> variable (if any), and define a known encoding to them so we won&#8217;t get into trouble while processing them afterwards. Of course, our example always expects to receive the additional data in JSON format, so this is why we create a new JSON instance from this data.</p>
<p>We use the <code>Select…Case</code> command to decide what method has to execute the web service, and that is based on the component stored in the <code>Path</code> property as you recall. So, if the request uses the <code>GetAll</code> method in the URL, we will call the real method <code>GetAllAlbums</code> in our Xojo code. After processing the information it will return a new <code>JSONItem</code> as the response we will send to the client.</p>
<p>How can we send the response to the request? Really simple: calling the <code>Write</code> method on the Response object, passing as parameter the text we want to send back. In our example, this is the <code>JSONItem</code> referenced by the <code>Output</code> variable. We also use the Response object to set the character encoding to UTF-8 and the MIME type to &#8220;Application/json&#8221;, in addition of setting the status value to 200 (that is, the request has been successfully handled).</p>
<p>If we receive a request with the <code>AddAlbum</code> method of our API, then we call the real <code>addNewAlbum</code> method in our Xojo code, passing as parameter the <code>JSONItem</code> object in charge of store the received data from the request (this is the one referenced by the <code>input</code> variable). In fact, the record structure is stored inside the <code>newAlbum</code> root node of the JSONItem.</p>
<h2>When it comes to the Database</h2>
<p>While <code>HandleURL</code> is in charge of processing the received request, we will use a couple of methods in our example app that will act as a <em>link</em> between the API and the database in the backend, both for retrieving and storing the requested information. (In a real world app it is very advisable to introduce checks and data sanitization before dealing with the database!)</p>
<p>Choose the <code>App</code> object again and use the <code>Insert &gt; Method</code> option in order to add the <code>GetAllAlbums</code> method, using the following method signature for that:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li><b>Method Name: </b>getAllAlbums</li>
<li><b>Return Type: </b>JSONItem</li>
<li><b>Scope: </b>Private</li>
</ul>
</li>
</ul>
<p>This is the code in charge of generating the JSONitem that we will <em>write </em>as part of the request response, including the <b>node</b> for every expected database record from the <code>Album</code> table in our example database:</p>
<pre>Var rc As RowSet = database.SelectSQL("Select * from album order by title asc") // Get the Recordset as result of the SQL selection: all the records
Var item As New JSONItem

If rc.RowCount &gt; 0 Then // We have records on the RecordSet
  
  While Not rc.AfterLastRow // so lets iterate them!
    Var d As New Dictionary // creating a new dictionary for each record, and that we will convert in a node
    d.Value("artistid") = rc.Column("artistid").StringValue // assingning the record ID to the name 'ArtistId' of the JSONItem
    d.Value("title") = rc.Column("title").StringValue // and the Title value to the 'Title' field of the JSONItem
    item.Value(rc.Column("albumid").StringValue) = d // You know you can assign a Dictionary as the value for a JSONItem node. Very useful!
    
    rc.MoveToNextRow
  Wend
  
  rc.Close
  
End If

var output As New JSONItem

output.Value("AllAlbums") = item // Then let's hang all these records form a main Node

Return output // And return it to the caller</pre>
<p>Next, create a new method named <code>addNewAlbum</code>. This is the one our web service will use to add a new record to the database, using for that the received data as part of the request. Use the following signature for the method definition:</p>
<ul>
<li style="list-style-type: none;">
<ul>
<li style="list-style-type: none;">
<ul>
<li><b>Method Name: </b>addNewAlbum</li>
<li><b>Paramters: </b>item as JSONItem</li>
<li><b>Scope:</b> Private</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>And put the following code in the associated Code Editor:</p>
<pre>Var title As String = item.Value("Title") // get the data associated to the "Title" field
Var artistid As String = item.Value("ArtistId") // and the 'ArtistID'

database.ExecuteSQL("insert into album(title,artistid) values(?, ?)", title, artistid ) // and insert that data as a new record into the database table
</pre>
<p>As you can see, the code is very simple: it gets the values for the received keys in the JSONitem nodes and uses them as part of the SQL sentence in order to add a new record to the database.</p>
<h1>A Web service… ready to serve!</h1>
<p>As you have seen, the code and app structure are really minimal! Of course, this is just a simple example but it gives you a good idea of the kind of possibilities web services offer and how fast you can put it together using Xojo and <strong>OOP</strong> concepts you already know! Of course, you can run your web app (and services) right from the IDE (just make sure to select 8081 as the Debug Port)… what is probably the recommended way to follow this simple example. For other more complex web apps, remember that you can use the one click solution <a href="https://www.xojo.com/cloud/"><strong>Xojo Cloud</strong></a> and of course any compatible Linux, Windows or Mac server.</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
<p>*<a href="https://www.aprendexojo.com/2016/06/crear-servicio-web-con-xojo/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 9 &#8211; Quote Web Service</title>
		<link>https://blog.xojo.com/2018/08/17/justcode-challenge-week-9-quote-web-service/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 10:00:24 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4829</guid>

					<description><![CDATA[We're wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.]]></description>
										<content:encoded><![CDATA[<p>We&#8217;re wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.</p>
<p><span id="more-4829"></span></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4831 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-15_12-22-31.png" alt="" width="591" height="490" /></p>
<p>The SQLite database has just a single table called Quote with this structure:</p>
<pre>CREATE TABLE Quote (
ID INTEGER NOT NULL,
QuoteText TEXT,
QuoteSource TEXT, 
PRIMARY KEY (ID)
);</pre>
<p>To randomly fetch a single quote from the table, this SQL is used:</p>
<pre>SELECT QuoteText, QuoteSource FROM Quote ORDER BY RANDOM() LIMIT 1;</pre>
<p>As companion apps, I&#8217;ve also included simple desktop and iOS apps that call the web service to display a quote.</p>
<p>The raw JSON that is returned looks like this:</p>
<pre>{"QuoteText":"Simple things should be simple. Complex things should be possible.","QuoteSource":"Alan Kay"}</pre>
<p>I&#8217;ve published a version of this on <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>. <a href="http://demos.xojo.com/QuoteService/">Access the app</a>.</p>
<p>Access the web service <a href="http://demos.xojo.com/QuoteService/index.cgi/api/quote">here</a>.</p>
<p>You can <a href="http://files.xojo.com/JustCode/QuoteService.zip">download the projects</a> or check it all out <a href="https://gitlab.com/xojo/QuoteService">on GitLab</a>.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49401-just-code-challenge-week-9-projects">week 9 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 8: <a href="https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/">JumpStart App Launcher</a></li>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Write a Slackbot in Less Than 20 Lines of Code</title>
		<link>https://blog.xojo.com/2016/01/12/write-a-slackbot-in-less-than-20-lines-of-code/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 12 Jan 2016 00:00:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Cats]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Slack]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/01/12/write-a-slackbot-in-less-than-20-lines-of-code/</guid>

					<description><![CDATA[Learn how to create a Slackbot for Slack in just a few lines of Xojo code.]]></description>
										<content:encoded><![CDATA[<p><strong>What is Slackbot?</strong></p>
<p>Slack has an API called &#8220;slash commands&#8221; that lets a user type a slash (/) followed by a command name in order to perform a special action. For example, Slack has <a href="https://get.slack.help/hc/en-us/articles/201259356-Using-slash-commands">many built-in slash commands</a>, one example is /help. Here&#8217;s how you can easily add your own slash commands using a Xojo web app and the HandleSpecialURL (or HandleURL) method.</p>
<p>Your slash command makes an HTTP request to your Xojo web service app. The web services does its thing and then returns the result back to Slack to display.</p>
<h2><span id="more-288"></span>A Xojo Web Service</h2>
<p>For demonstration, I&#8217;m going to show you how to create a Slackbot that returns a &#8220;cat fact&#8221;. The slash command will be /catfact. When you use the /catfact command, Slack calls a Xojo web service which then makes a call to the <a href="http://catfacts-api.appspot.com/doc.html">Cat Fact API</a>, parses the resulting JSON and returns an interesting cat fact back to Slack to display in your channel.</p>
<p><img decoding="async" style="width: 320px; display: block; margin-left: auto; margin-right: auto;" title="coding_cat.png" src="https://blog.xojo.com/wp-content/uploads/2016/01/coding_cat.pngt1466486449161ampwidth320" sizes="(max-width: 320px) 100vw, 320px" alt="coding_cat.png" width="320" /></p>
<p>As I&#8217;ve covered in a couple <a href="http://developer.xojo.com/webinar-web-services">Web Services webinars</a> last year, it is pretty easy to make a web service using Xojo. For this example, create a new web project and name it CatFact.</p>
<p>First you will create a simple method that will fetch a Cat Fact. Create a method on the App object, <strong>GetCatFact As String</strong>, with this code:</p>
<pre>// New request came in, so create a new HTTPSocket
Dim catSocket As New HTTPSocket

// Get a cat fact and wait for it to be returned
Dim factData As String = catSocket.Get("http://catfacts-api.appspot.com/api/facts?number=1", 30)

// Once the cat fact is returned, parse the JSON and send it to the original requester.
Dim jsonText As Text = DefineEncoding(factData, Encodings.UTF8).ToText
Dim jsonDict As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)
Dim facts() As Auto = jsonDict.Value("facts")

// Extract the fact text from the JSON
Dim fact As Text
If facts.Ubound &gt;= 0 Then
  fact = facts(0)
End If

Return fact</pre>
<p>In this Xojo project you&#8217;ll now create a simple web page UI to test that calling the Cat Fact API works. On the default page (WebPage1), add a Button and a TextField. In the Button&#8217;s Action event handler, add this code:</p>
<pre>CatFactArea.Text = App.GetCatFact</pre>
<p>Run the web app and on click the button. You should see a cat fact appear in the Text Area. The fact I got was:</p>
<p><strong>The cat has 500 skeletal muscles (humans have 650).</strong></p>
<p>Now you can add the code to process the web service request. Add the HandleSpecialURL event to the App object and use this code:</p>
<pre>If Request.Path = "CatFact" Then
  Request.Print(GetCatFact)
  Return True
End If</pre>
<p>You can test this by running the web project and then in a new tab entering the API URL, which displays a cat fact in the browser:</p>
<pre>http://127.0.0.1:8080/api/CatFact</pre>
<h2>Hook Up Web Service to Slack</h2>
<p>Now that you know the web service works, the next step is to hook it up to Slack. But before you can do that, you have to host the web app somewhere on the Internet; Slack can&#8217;t see your local web app! For this example, I&#8217;ve published the Cat Fact web service to <a href="http://developer.xojo.com/xojo-cloud">Xojo Cloud</a> because it&#8217;s fast and easy. This is the URL to the Cat Fact web service on Xojo Cloud:</p>
<pre>http://demos.xojo.com/CatFacts/index.cgi/api/CatFact</pre>
<p>Now you need to go to your Slack team settings to <a href="https://my.slack.com/services/new/slash-commands">add a slash command</a>. On that screen you&#8217;ll want to set the name of the <strong>Command</strong> to &#8220;/catfact&#8221; and the <strong>URL</strong> to &#8220;http://demos.xojo.com/CatFacts/index.cgi/api/CatFact&#8221; (the URL from above). Also change the <strong>Customize Name</strong> field to &#8220;CatFact&#8221;. You can ignore all the other fields and click the Save Integration button at the bottom.</p>
<p>That&#8217;s it. The slash command is now active. Head on over to your Slack team and type /catfact into a channel. You&#8217;ll get back a fact from &#8220;CatFact&#8221;.</p>
<p><img loading="lazy" decoding="async" title="SlackbotCatFact.png" src="https://blog.xojo.com/wp-content/uploads/2016/01/SlackbotCatFact.pngt1466486449161ampwidth578ampheight151" sizes="auto, (max-width: 578px) 100vw, 578px" alt="SlackbotCatFact.png" width="578" height="151" /></p>
<p>And it took less than 20 lines of code! You can now use this technique to integrate your own web services into Slack.</p>
<p>By default, only you will see the cat fact returned by the Slashbot; it is not broadcast to the entire channel. You can change this by returning specifically formatted JSON rather than just a text string (as described on the <a href="https://api.slack.com/slash-commands">Slack Commands API page</a>).</p>
<p>If you come up with a great slash command and want to make it available to the world, you can attach it to a <a href="https://api.slack.com/slack-apps">Slack app</a> and publish it to the <a href="https://slack.com/apps">App Directory</a>. The steps for this are also in the <a href="https://api.slack.com/slash-commands">Slash Commands API page</a>.</p>
<p style="text-align: center;"><!--HubSpot Call-to-Action Code --> <span id="hs-cta-wrapper-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-wrapper"> <span id="hs-cta-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-node hs-cta-7bcc3f87-4442-4a30-90b2-c9264729660a"><br />
<!-- [if lte IE 8]>


<div id="hs-cta-ie-element"></div>


<![endif]--> <a href="http://blog.xojo.com/2015/10/01/cats-up-using-httpsocket-with-the-cat-rest-api/" target="_blank"><img loading="lazy" decoding="async" id="hs-cta-img-7bcc3f87-4442-4a30-90b2-c9264729660a" class="hs-cta-img aligncenter" style="border-width: 0px;" src="https://blog.xojo.com/wp-content/uploads/2016/01/7bcc3f87-4442-4a30-90b2-c9264729660a.png" alt="Use HTTPSocket with Cat REST API" width="432" height="73" /></a> </span><script src="https://js.hscta.net/cta/current.js" charset="utf-8">// <![CDATA[
<script type="text/javascript"><![CDATA[ hbspt.cta.load(608515, '7bcc3f87-4442-4a30-90b2-c9264729660a', {});
// ]]&gt;</script></span><br />
<!-- end HubSpot Call-to-Action Code --></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Formatting SQL With A Web Service</title>
		<link>https://blog.xojo.com/2015/10/28/formatting-sql-with-a-web-service/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 28 Oct 2015 00:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2015/10/28/formatting-sql-with-a-web-service/</guid>

					<description><![CDATA[Formatting SQL for display can sometimes be a pain, particularly for the many different flavors of SQL. One easy way to do the formatting is to use a web service.]]></description>
										<content:encoded><![CDATA[<p>Formatting SQL for display can sometimes be a pain, particularly for the many different flavors of SQL. One easy way to do the formatting is to use a web service.</p>
<p><span id="more-273"></span></p>
<p>I did a little Google searching and found this one which seems to work well: <a href="https://github.com/sqlparser/sql-pretty-printer/wiki/SQL-FaaS-API-manual">https://github.com/sqlparser/sql-pretty-printer/wiki/SQL-FaaS-API-manual</a></p>
<p>To use it with Xojo, create a subclass of <a href="http://developer.xojo.com/xojo-net-httpsocket">Xojo.Net.HttpSocket</a> and drag it onto a window</p>
<p>This code in a button takes unformatted SQL from a TextArea and sends it to the web service, asking that it be formatted for Oracle (rqst_db_vendor=1):</p>
<pre> Dim sql As Text = SQLArea.Text.ToText
 Dim postText As Text = "rqst_input_sql=" + _
  EncodeURLComponent(sql).ToText + _
  "&amp;rqst_db_vendor=1"

 Dim postData As Xojo.Core.MemoryBlock
 postData = Xojo.Core.TextEncoding.UTF8.ConvertTextToData(postText)

 SQLFormatter1.SetRequestContent(postData, _
  "application/x-www-form-urlencoded")
 SQLFormatter1.Send("POST", _
  "http://www.gudusoft.com/format.php")

</pre>
<p>This code in the PageReceived event handler of your HttpSocket subclass parses the resulting JSON and displays the formatted SQL:</p>
<pre>Dim jsonText As Text
jsontText = Xojo.Core.TextEncoding.UTF8.ConvertDataToText(Content)
Dim json As Xojo.Core.Dictionary = Xojo.Data.ParseJSON(jsonText)
FormattedSQLArea.Text = json.Value("rspn_formatted_sql")</pre>
<p><a href="https://www.dropbox.com/s/f6xf60ew10z8saz/FormatSQLService.xojo_binary_project?dl=0">Download Sample Project</a></p>
<p>Looking for something to try next? Watch the video below and learn how to use <a href="http://developer.xojo.com/xojo-net-httpsocket">HTTPSocket</a><a href="http://developer.xojo.com/xojo-data"> </a>in the Xojo Framework.</p>
<p><span id="hs-cta-wrapper-80e618e0-e34d-4b07-8ed3-d3ac8eed66ae" class="hs-cta-wrapper"><span id="hs-cta-80e618e0-e34d-4b07-8ed3-d3ac8eed66ae" class="hs-cta-node hs-cta-80e618e0-e34d-4b07-8ed3-d3ac8eed66ae"> <!-- [if lte IE 8]>


<div id="hs-cta-ie-element"></div>


<![endif]--> <a href="http://developer.xojo.com/webinar-httpsocket" target="_blank"><img loading="lazy" decoding="async" id="hs-cta-img-80e618e0-e34d-4b07-8ed3-d3ac8eed66ae" class="hs-cta-img aligncenter" style="border-width: 0px; margin: 0 auto; display: block; margin-top: 20px; margin-bottom: 20px;" src="https://blog.xojo.com/wp-content/uploads/2015/05/80e618e0-e34d-4b07-8ed3-d3ac8eed66ae.png" alt="Watch the HTTPSocket Video" width="635" height="97" align="middle" /></a></span></span></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
