To answer this question it is important to know whether the API fully conforms to the principles of REST. A truly RESTful API uses hypermedia as the engine of application state (HATEOAS). The entire API can be used by a client that merely knows an entrypoint and the media types that are in use. Processing is guided by media types rather than the structure of the URI. Using such an architecture, the right thing to do would be to version the media types, e.g. by offering "application/vnd.someentity.v2" besides "application/vnd.someentity.v1" when breaking changes are necessary. Content Negotiation is used when a client needs a specific version.
If HATEOAS is not employed and generic media types are used, the client has to use what Roy Fielding calls out-of-band information in order to communicate which version is required. There are many ways to do that. The most popular one is to include the version number in the URI, as in "http://example.com/v1/someentity". Using query parameters or custom request headers are other means to communicate the expected version. In any case it is important to make sure that caching works, e.g. when request headers are used the Vary header should be supported.
GoatCounter is an open-source solution to this problem that respects privacy concerns and can be self-hosted. It calculates a hash of a site identifier, the user agent and the IP for each request. That way, unique visitors can be counted without saving any data from which a person could be identified. Unfortunately, this approach is somewhat imprecise since IPs are transient. A user who changes the wireless network also changes their IP address. However, there seems to be no correction for this that does not involve collecting a whole lot more data.
First of all, while there is more or less one stable option for Java, there exist many different libraries for JavaScript and some of them don't interact very well with Docker. As such, I recommend using the socket.io-client client library to implement the socket client.
Docker actually allows you to address your components via the names of their containers. So instead of using localhost or other IP addresses to connect to your container, you should specify the name of the container, for example use the address ws://socketserver:4001
if the name of the container that hosts the server is socketserver and it runs on port 4001. Furthermore, in your docker-compose file, you should make sure that there are no conflicts between exposed ports, and that the relevant port on the server is exposed. After that, your components should be able to interact with each other without any issues.
Let's break the implementation down into multiple steps. For the basic implementation, we want to keep a list of emails in your component's state, and when rendering, render a textbox for each email from this list. This will enable us to then easily add and remove textboxes by simply manipulating the DOM itself. For convenience, you can supply each textbox with an additional attribute that stores its index, although it is also possible to calculate this dynamically. At the end, you can render an additional textbox with placeholder text to enter the next email address. This will ensure that there is always at least one textbox (especially at the start before any data is entered), and that the user always has somewhere to type. The index of this placeholder textbox should be N, where N is the number of elements in the email list.
Next, you need to handle the onChange event for each of your textboxes. Here, you should check if the text is empty, and if so, delete the email corresponding to the index of the textbox from your list. Otherwise, update it to the new value to ensure consistency. When you remove an email, you should also focus the placeholder textbox for better usability.
Then we need to handle entry of characters into the placeholder textbox. As soon as the first character is entered into the placeholder textbox, instead of displaying there, you should intercept the event and add an additional entry to your email list. Focus the new textbox so that the remaining input goes there instead, while keeping the placeholder textbox empty. This gives the user the impression that the placeholder textbox turned into a regular textbox and a new placeholder textbox popped in below.
The last implementation detail is pasting a list of emails. To do this, intercept the onPaste event in the placeholder textbox. Keep in mind that you cannot rely on each system using the same line terminators. As such, since emails cannot contain whitespace, you should simply split the pasted content on whitespace characters. Optionally, you can check the emails you get for validity, and then add all the valid emails you have parsed to the email list in your component state. This will then make React create the required textboxes automatically, as with manual input.
One small detail that we need to address is validation. Contrary to popular belief, valid emails are not entirely trivial to validate. However, there exists a regular expression that correctly verifies virtually every email that adheres to standard conventions, namely ^(([^><()[\]\\.,;:\s@"]+(\.[^><()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))
You can use this expression to do your validation.
In IntelliJ, start by creating a new Kotlin project. You will be asked to choose the project type, at which point you can choose a pure frontend application or a full-stack web application depending on what suits your needs best. You may need to wait a few minutes for all the necessary dependencies to finish downloading.
You should then see your project. Within the src/main directory you will be able to find your main .kt file containing the script's starting point and an index.html file in the resources directory. Note that inside of the HTML file, the only script that is linked is one .js file, named the same as your project. This file will be generated at compile-time and will contain all your compiled Kotlin code.
To run the project, you can bring up the Gradle tool window from the View menu, and run the browserDevelopmentRun Gradle task to run your project for the first time. This may take a couple of minutes the first time you do it.
However, you probably don't want to be manually stopping and restarting your web server every time you make a change to a file. By bringing up your run configurations tool window, you can edit the newly created browserDevelopmentRun configuration. In the Arguments text field, add the argument --continuous and save your changes. Upon next run, this will make the system continuously listen for changes and update your browser automatically.
The answer is: it depends.
It depends on the programming language you are using and partially on the database you are using.
Most of the databases are services running on a web service. We can communicate with them using a special protocol, while we know the address and the port of the server where it runs. There are also databases stored in files, where we specify the target file.
Most of the programming lanugages and frameworks provide a "Connector" for databases, which allows us to communicate with the database. Of course you need to check if your programming language has a driver for the database type you want to connect to. Some frameworks or programming languaes also offer a higher level control structures called object-relational mapping, where the user can easily read or write some objects defined in the project.
There are many different possibilities to answer this question. We will go top down beginning with the browser.
Most of the browsers support the html input tag of type "email" and most of them would automatically warn the user about a wrong format of the address. However there are many standards of email address pattern. Furthermore the user might disable the browser validation, so we should not rely on this.
The second station is the javascript of the browser. Probably the easiest way to validate the email address is to use a regular expression an match the input against this expression. However the user may disable the javascript or send a request in other way than browser. Therefore it's absolutely necessary to validate the email address on the server side. This might be done by a regular expression, but some more sophisticated systems would check the MX record of the domain given in the email address, to be sure it might be a real address of a real mail server.