Company " 1C» is actively developing the 1C:Enterprise platform and adding new features with each release. After the start of development of the 8.3 branch, a lot of new products began to appear, and due to constant busyness, you don’t have time to try them all out. Not long ago I how to develop a full-fledged mobile application(yes, on "1C:Enterprise"), and today I would like to talk about creating HTTP services by means of the platform.
Possibility of development HTTP services appeared as part of the configuration in the version 8.3.5 . During this time, the component was updated several times, and today it is quite possible to use it without fear of the presence of “childish” errors. I have not yet had the opportunity to use the functionality of the 1C:Enterprise platform to create http services in real conditions, so so far my experience is limited to educational projects. However, I see prospects for using the http services mechanism in one of the current working projects. In this series of short notes I will try to show typical examples of use http services in configurations for the platform " 1C:Enterprise».
Creating a simple http service in 1C:Enterprise 8.3
Today we will look at an example of the simplest http service, and then we will improve and complicate it. The purpose of the lesson is to understand and experience the simplicity of creation http services based on the 1C:Enterprise 8.3 platform.
Let's start with the formulation of the problem. The service created within the framework of the note must be able to do only two things: accept a GET request and return a response in JSON format. The task is trivial and doing something similar in PHP/ASP .NET is a matter of a few lines of code. Looking ahead, I’ll say that in 1C:Enterprise we will need about the same amount (okay, don’t laugh at the oddities of the 1C platform).
We’ll talk about use cases for http services in a separate post, but for now we’ll just create a new http service. For convenience, we will create a new information base with an empty configuration. Let’s add one subsystem to it, which we’ll call “ Testing HTTP Services" Now let’s open the “General” section in the configuration tree and find the group “ HTTP services» and add the first web service. In the window for creating a new service, fill in the fields:
- Name- FirstWebService;
- Synonym- First web service;
- Root URL- our-services;
Pay attention to the field " Root URL" The name specified here will be used when accessing the service. There should be no spaces here and it is advisable not to use the Cyrillic alphabet. We’ve sorted this out, then go to the “ Subsystems" and add the http service to the only available subsystem.
The next step is to describe the URL pattern. Let's go to the appropriate tab and add a template with the name " Display List of Services" In the Property Inspector we will find the property " Sample" and write in it " /list" By doing this, we will set the path along which interaction with the http service will take place. The template may contain special characters that allow you to specify the parameters passed (both required and not), but for the first example we will limit ourselves to a simple " /list" When going along this path, our only method will work and give the client a set of data.
Great, there is a template, now it’s up to the method. Let's add for our template, which we'll call getServicesList. In the property inspector, we need to specify the HTTP method. The specified value determines what types of requests our method will respond to. The current task makes it possible to get by using the “ GET”.
Our service is almost ready, all that remains is to register an event handler for the constructed method getServicesList. You can create an event handler through the property inspector. In the body of the handler we write:
Function OutputIndexgetServicesList(Request) ArrayServices = New Array; Array of Services.Add(New Structure("title, description", "Service No. 1", "Description of service No. 1")); Array of Services.Add(New Structure("title, description", "Service No. 2", "Description of service No. 2")); Array of Services.Add(New Structure("title, description", "Service No. 3", "Description of service No. 3")); Array of Services.Add(New Structure("title, description", "Service No. 4", "Description of service No. 4")); EntryJSON = New EntryJSON; RecordJSON.SetString(); WriteJSON(WriteJSON, ArrayServices); StringForResponse = JSONRecord.Close(); Response = New HTTPServiceResponse(200); Response.Headers.Insert("Content-type", "application/json; charset=utf-8"); Response.SetBodyFromString(StringForResponse, TextEncoding.UTF8, UseByteOrderMark.NotUse); Return Reply; EndFunction
Let's look at the above code in a little more detail. At the very beginning I describe an array consisting of structures. We need this array purely for demonstration. We will convert all its contents into JSON and give it to the client. Initializing an object of type JSON entry. Be sure to call the method SetString(), because we need to get the JSON text into a string variable. Next we call the global method WriteJSON(), to which we pass an object of type JSON entry and the array that needs to be converted. Next we get the result into the variable “ LineForResponse" and prepare an HTTP response.
In response we add (see method " SetBodyFromString") the resulting JSON. That's it, the demo code is ready and you can move on to tests.
Publishing an HTTP service in 1C:Enterprise 8.3
Let's publish the created HTTP service to test the results of the work done. For the simplest test, a web server must be installed on your system. For me the role of a web service is performed by Apache. We will skip the steps required to install/configure a web server and move on to the issue of publishing an HTTP service.
To publish, you must go to the “Administration” menu and select “ Publishing to a web server" In the window that appears, fill in:
- Name is the name of our solution. It will be used in the URL when accessing the published information security. For example, if you specify test here, your information security will be available at http://localhost/test. I'm happy with the test option.
- Web server- Filled in automatically. I use Apache 2.2 as a web server;
- Catalog– path to the directory in which the configuration file of the published IS will be placed;
- Uncheck the " Publish thin client and web client», « Publish standard OData interface», « Publish WEB services by default»;
- On the HTTP Services tab, check the “ Publish HTTP services by default" and in the tabular section we mark the created service.
Testing the HTTP service
To test the created http service, let's launch a browser and try to access it. If you repeated all my steps, then the path should look like this:
Http://localhost:9090/services/hs/our-services/list
It is worth paying attention to the port 9090 , which is specified with a colon after the hostname. If you installed Apache with default settings, then it will listen on port 80, therefore, you do not need to specify anything. As a result, the URL will be like this:
Http://localhost/services/hs/our-services/list
Try to navigate through it, and if everything works correctly, you will receive a page with data in JSON format:
[ ( title: "Service No. 1", description: "Description of Service No. 1" ), ( title: "Service No. 2", description: "Description of Service No. 2" ), ( title: "Service No. 3", description: "Description of service No. 3", ( title: "Service No. 4", description: "Description of service No. 4") ]
This is where we can end our consideration of the demo example, but I would like to finally parse the URL into its component elements so that it is clear why we received exactly such a link.
So, the first part should be clear - localhost. This is the hostname where the web server is installed. Next is a link (services) to the published information security. Next comes hs, this path element indicates that we are interested in interacting with the http service. The last two elements are the root URL of our service and the URL template.
Instead of a conclusion
« 1C:Enterprise 8.3» allows you to create simple HTTP services with a minimum of labor costs, which is what you should have been convinced of after reading this short note. The functionality significantly expands the platform's application options. In the following posts we will talk about practical cases of using the technology and consider the implementation of various solutions in practice.
Web services is one of the platform mechanisms used for integration with other information systems. It is a means of supporting SOA (Service-Oriented Architecture), a service-oriented architecture that is a modern standard for integrating applications and information systems.
A significant advantage of service-oriented architecture is that it allows you to develop the enterprise infrastructure in a uniform way, without destroying existing solutions. Its use allows you to minimize costs by integrating heterogeneous and legacy systems into the modern enterprise landscape. It allows you to implement loosely coupled software components in order to maximize their reuse.
Service-oriented architecture is being intensively developed and supported by major vendors. It is built on the basis of services, autonomous or managed externally. The preferred way to implement them is through web services. They are platform independent, standalone, and supported everywhere.
Application solution 1C:Enterprise 8 can be both a provider of web services and a consumer of web services published by other providers.
Systems using arbitrary hardware and software platforms can act as consumers. Web services technology is platform independent.
![](https://i1.wp.com/v8.1c.ru/overview/000000273_2.png)
Technical implementation of web services
If the application solution is a web service provider, then in both the file and client-server modes of operation, the interaction between the application solution and web service consumers is carried out through the web server, using the web server extension module.
In this case, when a consumer accesses the web service of an application solution, the web service module is executed. This module is contained in the configuration and contains procedures that are executed when calling certain web service operations.
In the case of a client-server version of work, this module will be executed in a cluster. In the case of the file version of work - in the web server extension module.
If the application solution is a consumer of a third-party web service provider, then in this case the interaction between the application solution and the web service provider is carried out
I know that on Habré they don’t really like the long-suffering 1C. Although, with the release of platform 8.3 (with clients for Linux), they began to love it a little more. By the way, just recently the interface of one of the main 1C developments - the Manufacturing Enterprise Management configuration - was completely translated into English. Many times I have come across questions about why they don’t write about 1C here. The answer to them is quite obvious - there are many specialized resources where you can quickly discuss all the questions and read something.
There is every reason to believe that this article will not survive here, but I will still take the risk, because there are some interesting things in 1C that are worth talking about.
For some time now, 1C 8.x has made it possible to use web services: 1C can act as both a supplier and a consumer. In this article I will show how to use 1C as a consumer using the example of receiving exchange rates from the Central Bank server.
Web service
The Central Bank has a web service for receiving daily data: exchange rates, news, exchange rate dynamics, etc. A description of the service can be found here http://www.cbr.ru/scripts/Root.asp?Prtid=DWS. We are interested in one of the methods of this service: GetCursOnDate(On_date)– obtaining exchange rates for a given date. One argument is passed to the method On_date– this is the date on which you need to receive the courses. The result is XML containing the table ValueCursOnDate(the courses themselves and related information).Configuration
For development, I took 1C 8.2 (8.2.15.317 in my case) and created an empty configuration. To use external web services, a WS link object is provided, but it is not necessary to use it; the service can be accessed dynamically from code. I'll use the first option and then show how you can use the second. In the configuration, I created a processing and called it “Loading CBR Currency Rates”. I added a form (managed) and made it the main one. I created the details on the form and placed the controls as shown in the figure.Now the most important thing is to create a link to the description of the web service. In the configuration we add a new object of type WS-link. In the window that appears, indicate the link to the WSDL (a description of this format is beyond the scope of the article, you can read about it on Wikipedia): http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL.
Based on the received description, 1C will automatically create a visual map of the web service. You can see the name of the web service, see what operations are available to it, as well as the data types used.
The configuration is almost complete, we just need to do a couple of touches to make our application look more aesthetically pleasing. Right-click on the configuration root and call up the “Open desktop command interface” menu. In the window that appears, you need to uncheck the “Visibility” flag next to the “Loading Central Bank currency rates” processing. Click the OK button. Next, right-click on the configuration root and call the “Open desktop workspace” menu, there we will make the settings as in the figure:
These settings will allow us to display the processing form directly on the desktop (meaning the desktop of the 1C program) in 1C Enterprise mode.
Programming
Now all that remains is to fill our processing with meaning: make it receive exchange rates and display it in a table on the form. In the form editing mode, you need to add a new form command, let's call it LoadCurrencies. This command must be associated with a button located on the form. Let's fill in the action for the command with the following code (author's note: wow, the hub has 1C code highlighting, although it doesn't work correctly):&On the Client Procedure LoadCurrencies(Command) If NOT ValueFilled(DownloadDate) Then Report("Download date not selected!", MessageStatus.Important); Return; endIf; CurrencyRatesTable.Clear(); LoadCurrencyRates(LoadDate); End of Procedure
Here, we first check whether the date is filled in (if it is not filled in, then we inform the user about it and do nothing else). Then the table located on the form is cleared and the LoadCurrencyRates() procedure is called, to which the date is passed.
Code of the procedure LoadCurrencyRates(), explanations are given in the comments to the code:
Procedure LoadCurrencyRates(fDataDownload) //Create a proxy to access an external web service, //pass the namespace URI, service name, port name to the function. Proxy = WSLinks.CBR_DailyInfoWebServ.CreateWSProxy("http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap"); //Get the type of the parameter that is passed to the GetCursOnDate method. TypeWSParameter = Proxy.FactoryXDTO.Packets.Get("http://web.cbr.ru/").Get("GetCursOnDate"); //Create a parameter based on the type and fill in the value of the On_Date parameter. WSParameter = Proxy.XDTO Factory.Create(WSParameterType); WSParameter.On_Date = fLoadDate; //Call the web service method, write the result to the Currency Rates variable. Currency rates = Proxy.GetCursOnDate(WSParameter); //Loop through the ValuteCursOnDate table, add each table value //to the table on the form (fill the columns with the corresponding values). For Each Element From Currency Rates.GetCursOnDateResult.diffgram.ValuteData.ValuteCursOnDate Cycle NewLineTK = CurrencyRatesTable.Add(); NewLineTK.CurrencyName = Element.Vname; NewStringTZ.Nominal = Element.Vnom; NewLineTZ.DigitalCurrencyCode = Element.Vcode; NewTZLine.CurrencyCode = Element.VChCode; NewLineTZ.Currency Rate = Element.Vcurs; EndCycle; End of Procedure
Now you can update the database configuration (F7) and launch 1C Enterprise (F5). If you did everything correctly, you should see a window like the one below:
To check the result, we need to enter the date for which we want to receive exchange rates and click on the “Load currencies” button. If the request is successful, the table on the form will be filled with rate values:
Finally, I want to show how you can dynamically access an external web service, that is, without adding a WS link object. Thus, we can consume such web services from external processing without being tied to configuration.
In the LoadCurrencyRates() procedure, a line
Definitions = New WSDefinitions("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL"); Proxy = New WSProxy(Definitions, "http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
First we create so-called definitions for the web service from its WSDL. Then we also create a proxy to access it.
As you can see, using external web services from 1C is generally quite simple (although there is some difficulty in understanding the definition of types, including me).
If this post resonates here, there are a few other topics to talk about.
July 30, 2012 at 01:19 pmUsing external web services in 1C using the example of loading exchange rates
- Programming
I know that on Habré they don’t really like the long-suffering 1C. Although (with clients running Linux), they began to like it a little more. By the way, just recently the interface of one of the main 1C developments - the Manufacturing Enterprise Management configuration - was completely translated into English. Many times I have come across questions about why they don’t write about 1C here. The answer to them is quite obvious - there are many specialized resources where you can quickly discuss all the questions and read something.
There is every reason to believe that this article will not survive here, but I will still take the risk, because there are some interesting things in 1C that are worth talking about.
For some time now, 1C 8.x has made it possible to use web services: 1C can act as both a supplier and a consumer. In this article I will show how to use 1C as a consumer using the example of receiving exchange rates from the Central Bank server.
Web service
The Central Bank has a web service for receiving daily data: exchange rates, news, exchange rate dynamics, etc. A description of the service can be found here http://www.cbr.ru/scripts/Root.asp?Prtid=DWS. We are interested in one of the methods of this service: GetCursOnDate(On_date)– obtaining exchange rates for a given date. One argument is passed to the method On_date– this is the date on which you need to receive the courses. The result is XML containing the table ValueCursOnDate(the courses themselves and related information).Configuration
For development, I took 1C 8.2 (8.2.15.317 in my case) and created an empty configuration. To use external web services, a WS link object is provided, but it is not necessary to use it; the service can be accessed dynamically from code. I'll use the first option and then show how you can use the second. In the configuration, I created a processing and called it “Loading CBR Currency Rates”. I added a form (managed) and made it the main one. I created the details on the form and placed the controls as shown in the figure.Now the most important thing is to create a link to the description of the web service. In the configuration we add a new object of type WS-link. In the window that appears, indicate the link to the WSDL (a description of this format is beyond the scope of the article, you can read about it on Wikipedia): http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL.
Based on the received description, 1C will automatically create a visual map of the web service. You can see the name of the web service, see what operations are available to it, as well as the data types used.
The configuration is almost complete, we just need to do a couple of touches to make our application look more aesthetically pleasing. Right-click on the configuration root and call up the “Open desktop command interface” menu. In the window that appears, you need to uncheck the “Visibility” flag next to the “Loading Central Bank currency rates” processing. Click the OK button. Next, right-click on the configuration root and call the “Open desktop workspace” menu, there we will make the settings as in the figure:
These settings will allow us to display the processing form directly on the desktop (meaning the desktop of the 1C program) in 1C Enterprise mode.
Programming
Now all that remains is to fill our processing with meaning: make it receive exchange rates and display it in a table on the form. In the form editing mode, you need to add a new form command, let's call it LoadCurrencies. This command must be associated with a button located on the form. Let's fill in the action for the command with the following code (author's note: wow, the hub has 1C code highlighting, although it doesn't work correctly):&On the Client Procedure LoadCurrencies(Command) If NOT ValueFilled(DownloadDate) Then Report("Download date not selected!", MessageStatus.Important); Return; endIf; CurrencyRatesTable.Clear(); LoadCurrencyRates(LoadDate); End of Procedure
Here, we first check whether the date is filled in (if it is not filled in, then we inform the user about it and do nothing else). Then the table located on the form is cleared and the LoadCurrencyRates() procedure is called, to which the date is passed.
Code of the procedure LoadCurrencyRates(), explanations are given in the comments to the code:
Procedure LoadCurrencyRates(fDataDownload) //Create a proxy to access an external web service, //pass the namespace URI, service name, port name to the function. Proxy = WSLinks.CBR_DailyInfoWebServ.CreateWSProxy("http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap"); //Get the type of the parameter that is passed to the GetCursOnDate method. TypeWSParameter = Proxy.FactoryXDTO.Packets.Get("http://web.cbr.ru/").Get("GetCursOnDate"); //Create a parameter based on the type and fill in the value of the On_Date parameter. WSParameter = Proxy.XDTO Factory.Create(WSParameterType); WSParameter.On_Date = fLoadDate; //Call the web service method, write the result to the Currency Rates variable. Currency rates = Proxy.GetCursOnDate(WSParameter); //Loop through the ValuteCursOnDate table, add each table value //to the table on the form (fill the columns with the corresponding values). For Each Element From Currency Rates.GetCursOnDateResult.diffgram.ValuteData.ValuteCursOnDate Cycle NewLineTK = CurrencyRatesTable.Add(); NewLineTK.CurrencyName = Element.Vname; NewStringTZ.Nominal = Element.Vnom; NewLineTZ.DigitalCurrencyCode = Element.Vcode; NewTZLine.CurrencyCode = Element.VChCode; NewLineTZ.Currency Rate = Element.Vcurs; EndCycle; End of Procedure
Now you can update the database configuration (F7) and launch 1C Enterprise (F5). If you did everything correctly, you should see a window like the one below:
To check the result, we need to enter the date for which we want to receive exchange rates and click on the “Load currencies” button. If the request is successful, the table on the form will be filled with rate values:
Finally, I want to show how you can dynamically access an external web service, that is, without adding a WS link object. Thus, we can consume such web services from external processing without being tied to configuration.
In the LoadCurrencyRates() procedure, a line
Definitions = New WSDefinitions("http://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL"); Proxy = New WSProxy(Definitions, "http://web.cbr.ru/", "DailyInfo", "DailyInfoSoap");
First we create so-called definitions for the web service from its WSDL. Then we also create a proxy to access it.
As you can see, using external web services from 1C is generally quite simple (although there is some difficulty in understanding the definition of types, including me).
If this post resonates here, there are a few other topics to talk about.
The topic title is really a question, because... I myself don’t know what it is and for the first time I will try to work with it within the framework of this article. The only thing I can guarantee is that the code presented below will work, but my phrases will only be assumptions and guesses about how I myself understand all this. So, let's go...
Introduction
We need to start with why the concept of web services was created. By the time this concept appeared in the world, technologies already existed that allowed applications to interact at a distance, where one program could call some method in another program, which could be launched on a computer located in another city or even country. All this is abbreviated as RPC (Remote Procedure Calling). Examples include CORBA technologies, and for Java - RMI (Remote Method Invoking). And everything seems to be good in them, especially in CORBA, because... You can work with it in any programming language, but something was still missing. I believe that the disadvantage of CORBA is that it works through some of its own network protocols instead of simple HTTP, which will fit through any firewall. The idea of the web service was to create an RPC that would be inserted into HTTP packets. Thus began the development of the standard. What are the basic concepts of this standard:- SOAP. Before calling a remote procedure, you need to describe this call in an XML file in SOAP format. SOAP is simply one of the many XML markups that are used in web services. Everything we want to send somewhere via HTTP is first converted into an XML SOAP description, then stuffed into an HTTP packet and sent to another computer on the network via TCP/IP.
- WSDL. There is a web service, i.e. a program whose methods can be called remotely. But the standard requires that this program be accompanied by a description that says that “yes, you’re right - this is really a web service and you can call such and such methods from it.” This description is represented by another XML file, which has a different format, namely WSDL. Those. WSDL is just an XML file describing a web service and nothing more.
General approach
In web services there is always a client and a server. The server is our web service and is sometimes called the endpoint (as in, the end point where SOAP messages from the client reach). We need to do the following:- Describe the interface of our web service
- Implement this interface
- Launch our web service
- Write a client and remotely call the desired web service method