JakobMiksch / osm-feature-info

Attempt to create an API to get information about OSM features around a location.
0 stars 0 forks source link

ensure JSON is not stringified #3

Closed JakobMiksch closed 2 weeks ago

JakobMiksch commented 7 months ago

currently our response is:

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [
            8.7551143,
            53.1193666
        ]
    },
    "properties": {
        "osm_id": 3681752122,
        "osm_type": "N",
        "tags": "{\"railway\": \"level_crossing\", \"crossing:barrier\": \"no\"}"
    }
}

we want to have the tags property to be a proper JSON

related https://github.com/CrunchyData/pg_featureserv/issues/155

iboates commented 7 months ago

It seems to me like this is a limitation of pg_featureserv itself. I can think of three ways to solve this:

  1. Use something else where we have more direct control over the structure of the returned JSON (e.g. Flask, express), but I think that this is out of the question.
  2. Make it the frontend's problem. The UI would have to run f.properties.tags = JSON.parse(f.properties.tags) for every feature f. This could become a performance problem for the client.
  3. (My preference) Write a very simple middleware server to sit between the client and the server which simply forwards all client requests to the server, then applies the same JSON parsing operation as in 2. Here is a simple ChatGPT-generated example of this:
from flask import Flask, request, jsonify
import requests
import json

app = Flask(__name__)

@app.route('/forward-request', methods=['GET'])
def forward_request():
    # Assuming the target URL is stored in the TARGET_URL environment variable or hardcoded
    target_url = "http://example.com/target-server"  # Replace with your target server URL

    # Forward the incoming query parameters to the target server
    response = requests.get(target_url, params=request.args)

    # Check if the request was successful
    if response.status_code == 200:
        try:
            # Try to parse the JSON response
            data = response.json()

            # Extract, parse, and replace the 'tags' value within 'data["properties"]'
            if "properties" in data and "tags" in data["properties"]:
                tags_json_str = data["properties"]["tags"]
                tags_json = json.loads(tags_json_str)  # Convert the string to JSON
                data["properties"]["tags"] = tags_json  # Replace the string with the JSON object

            # Return the modified JSON
            return jsonify(data)
        except ValueError:
            # In case the response is not in JSON format or parsing failed
            return jsonify({"error": "Invalid JSON response from target server"}), 500
    else:
        return jsonify({"error": "Failed to fetch data from target server"}), 500

if __name__ == '__main__':
    app.run(debug=True)

What do you think?

JakobMiksch commented 7 months ago

I think the best way is to fix this directly in pg_featureserv related https://github.com/CrunchyData/pg_featureserv/issues/155

iboates commented 7 months ago

Alright, well I will need to learn a lot more about Go before I am able to fix it there. Do you have an idea on how to fix it? I would love to see how you do it to see how to work on a Go codebase properly.

JakobMiksch commented 7 months ago

I need to get into the code base as well but we can also have a look together

JakobMiksch commented 7 months ago

this fix might solve this issue: https://github.com/CrunchyData/pg_featureserv/pull/165