Function HTTP_Users_Services(RemainingURL) /*********************************************************************************************************************** This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written permission from SRP Computer Solutions, Inc. Name : HTTP_Users_Services Description : Handler program for the HTTP Users service module. Notes : All HTTP web services should include the HTTP_SERVICE_SETUP insert. This will provide several useful variables: HTTPMethod - The HTTP Method (Verb) submitted by the client (e.g., GET, POST, etc.) APIURL - The URL for the API entry point (e.g., api.mysite.com/v1). SelfURL - The URL path representing the current service. FullEndPointURL - The URL submitted by the client. This can be the same or longer than the SelfURL. NextSegment - The URL segment immediately following the SelfURL (if any). This could contain the name of the next service or it could contain the Item ID for the current service (aka resource). CurrentServiceHandler - The name of this stored procedure. Parameters : RemainingURL [in] -- The remaining portion of the URL that follows the URL that launched this current service. This information is used in the HTTP_SERVICE_SETUP insert to populate other useful variables (see Notes above). Response [out] -- Response to be sent back to the Controller (HTTP_MCP) or requesting procedure. Web API services do not rely upon anything being returned in the response. This is what the various services like SetResponseBody and SetResponseStatus services are for. A response value is only helpful if the developers want to use it for debug purposes. History : (Date, Initials, Notes) 04/17/15 dmb Original programmer. - [SRPFW-94] 05/22/15 dmb Retrofit using the new template from HTTP_Contacts_Services and relying upon the HTTP_Resources_Services module. - [SRPFW-94] 03/09/16 dmb Refactor to use the updated RunHTTPService service. - [SRPFW-112] 07/01/17 dmb Refactor using Enhanced BASIC+ syntax. - [SRPFW-184] ***********************************************************************************************************************/ #pragma precomp SRP_PreCompiler $insert APP_INSERTS $insert HTTP_SERVICE_SETUP $insert HTTP_INSERTS // Assume the current HTTP method is valid until proven otherwise. ValidMethod = True$ // Assume the current web service is valid until provent otherwise. ValidService = True$ // Assume no HTTP methods are valid until proven otherwise. AllowedMethods = '' // A list of all services able to be called from this URL. AllowedServices = '' // Some methods are restricted to authorized users only. Get their security level for cross-checking later. Username = Memory_Services('GetValue', 'Username') Security = Xlate('USERS', Username, 'ACCESS_LEVEL', 'X') // Handle the HTTP request as needed. Begin Case Case RemainingURL _EQC '' // This means the URL ends with /users, which means this is the end point. The client is requesting a // collection of all users. AllowedMethods = 'POST,GET,OPTIONS' Locate HTTPMethod in AllowedMethods using ',' setting MethodPos then On MethodPos GoSub Post, Get, Options end else ValidMethod = False$ end Case Count(RemainingURL, '/') EQ 0 // This means the URL ends with /users/{KeyID}. The client is requesting a specific user item. AllowedMethods = 'PUT,GET,DELETE,OPTIONS' Locate HTTPMethod in AllowedMethods using ',' setting MethodPos then On MethodPos GoSub PutItem, GetItem, DeleteItem, OptionsItem end else ValidMethod = False$ end Case Otherwise$ ValidService = False$ End Case // Resolve any invalid conditions with the HTTP request. Begin Case Case Not(ValidService) HTTP_Services('SetResponseStatus', 404, NextSegment : ' is not a valid service request within the ' : CurrentServiceHandler : ' module.') Case Not(ValidMethod) HTTP_Services('SetResponseStatus', 405, HTTPMethod : ' is not valid for this service.') GoSub SetAllowedMethods End Case Return Response OR '' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Service Parameter Options //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Options BOOLEAN = True$, False$ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Web Services //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // Post // // Attempts to create a new user. //---------------------------------------------------------------------------------------------------------------------- Post: HTTP_Resource_Services('PostDatabaseItem', 'USERS', SelfURL) return //---------------------------------------------------------------------------------------------------------------------- // Get // // Returns a collection of users. This URL also supports the passing in of query parameters, which in this case will // will only support "name" as the query param field. //---------------------------------------------------------------------------------------------------------------------- Get: HAL = '' ; // Initialize the response. If HTTP_Services('GetHTTPGetString') NE '' then // This means the URL ends with /users?name={value}. NameSearch = HTTP_Services('GetQueryField', 'name') Filter = 'SELECT USERS BY USERNAME WITH USERNAME CONTAINING ' : Quote(NameSearch) ColumnNames = 'first_name' : @FM : 'last_name' HAL = HTTP_Resource_Services('GetDatabaseItems', Filter, 'USERS', SelfURL, ColumnNames) end else // This means the URL ends with /users. The client is requesting all users available at this URL. Filter = '' ColumnNames = 'first_name' : @FM : 'last_name' HAL = HTTP_Resource_Services('GetDatabaseItems', Filter, 'USERS', SelfURL, ColumnNames) end Response = HAL return //---------------------------------------------------------------------------------------------------------------------- // Options // // Sets the appropriate response header fields for an OPTIONS request. //---------------------------------------------------------------------------------------------------------------------- Options: GoSub SetCommonOptionResponseHeaders return //---------------------------------------------------------------------------------------------------------------------- // PutItem // // Attempts to update a user. If the user does not already exist then a new one will be created. //---------------------------------------------------------------------------------------------------------------------- PutItem: KeyID = NextSegment HTTP_Resource_Services('PutDatabaseItem', 'USERS', SelfURL : '/' : KeyID, KeyID) return //---------------------------------------------------------------------------------------------------------------------- // GetItem // // Returns the specific user. //---------------------------------------------------------------------------------------------------------------------- GetItem: KeyID = NextSegment ColumnNames = 'first_name' : @FM : 'last_name' HAL = HTTP_Resource_Services('GetDatabaseItem', 'USERS', SelfURL : '/' : KeyID, KeyID, ColumnNames) Response = HAL return //---------------------------------------------------------------------------------------------------------------------- // DeleteItem // // Attempts to delete the user. //---------------------------------------------------------------------------------------------------------------------- DeleteItem: KeyID = NextSegment HTTP_Resource_Services('DeleteDatabaseItem', 'USERS', KeyID) return //---------------------------------------------------------------------------------------------------------------------- // OptionsItem // // Sets the appropriate response header fields for an OPTIONS request. //---------------------------------------------------------------------------------------------------------------------- OptionsItem: GoSub SetCommonOptionResponseHeaders return //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Internal GoSubs //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------------------------------------------------- // SetCommonOptionResponseHeaders // // Sets the response headers that will be common for all OPTIONS methods. //---------------------------------------------------------------------------------------------------------------------- SetCommonOptionResponseHeaders: HTTP_Services('SetResponseHeaderField', 'Access-Control-Allow-Headers', 'authorization', True$) HTTP_Services('SetResponseHeaderField', 'Access-Control-Allow-Headers', 'x-authorization', True$) HTTP_Services('SetResponseHeaderField', 'Access-Control-Max-Age', 1728000) GoSub SetAllowedMethods return //---------------------------------------------------------------------------------------------------------------------- // SetAllowedMethods // // Sets the Allow response header field as appropriate for the requested URL. //---------------------------------------------------------------------------------------------------------------------- SetAllowedMethods: If AllowedMethods NE '' then For Each Method in AllowedMethods using ',' HTTP_Services('SetResponseHeaderField', 'Allow', Method, True$) Next Method end return