I am building a REST service. This services enables the user to create an entity that has an Address. For simplification, let say this other entity is 'House', so 'A House has an Address'.
The system has to geocode every House so along with the Address, a House must have latitude/longitude at the moment of being created, but those are not requested to the user.
The user will be asked to enter an Address. From this address the system will try to retrieve latitude/longitude using a third party service. This service will return the best match for the address entered by the user, so sometimes it will return a different address (e.g could happen that there is two different streets with the same name in different cities and the services could return information regarding the wrong one).
I have to make sure that the address I am storing with the House is the one the user wanted, so the workflow for the user would be something like this:
- The user wants to create a new House.
- The user Enter an address.
- The user sees the best match for that address in a map.
- The user confirms that the address is OK.
- The system saves the House with the address and the lat/long retrieved from the service.
Approach 1
The entities model would be:
- House has an Address
- Address has a Coordinates (lat/long)
and I would have an endpoint for POST addresses and another for POST houses. The workflow would be:
- The user wants to create a new House.
- The user Enter an address and make a POST to the addresses endpoint.
- The system retrieves the lat/long for the best match.
- The system saves the address retrieved by the geocoding service in the DB. Note that it can be different from the address the user entered.
- As a response to the POST request, the system returns the address that have saved and show it to the user.
- The user confirms that the address is OK.
- The system makes a POST to the houses endpoint with the ID for the address that has been created before, so in DB the house will be linked to the address that was created before.
With this approach, if the user doesn't accept the address provided, I would end up with some 'orphan' addresses (addresses that are not linked to any House). I would need to make a periodic clean on the DB for those addresses.
Approach 2
In this approach, I would have an endpoint /validate-address, so the user would POST an address, and the system would returns the best match. Nothing would be created in the DB at this point. The user then would accept the returned address and would make a POST to /houses with the information of the house and the address.
With this approach, I cannot assure that all the Address in the DB are correctly geocoded as some user could make a POST to /houses without a previous call to /validate-address.
Also, it doesn't seem quite right from a REST perspective to have a POST /validate-address request that doesn't create anything on the DB.
What would be the best approach to this situation? Can you see an alternative approach to this two? Any feedback would be appreciated.
addresses
andhouses
separate endpoints? Do you expect an address to be bound to multiple houses or the other way round? Can't you make the first request aGET
, save nothing to the database, keep all of the options retrieved from the geoservice in the response (as hypertext) and allow the user to issue a finalPOST
request carrying all of the data (long/lat, address, other house data) to a single endpoint (be it houses or addresses)? The possible addresses would be in the response and the user could just select the one to actually use to create a resource.