3

I have created a serverless GraphQL API function with Azure functions and have connected it to Cosmos DB. I have been trying to fix the issue that says Invalid URL(snip below) for a week now, but so far I have no clue on whats going on. When I run the graphql function locally it works. Please ask if you need anything added to this post.

Here is my index.ts -

import { ApolloServer } from "apollo-server-azure-functions"
import { BolDataSource } from "../data-sources/models/bol-datasource";
import { typeDefs } from './graphql-schema';


const resolvers = {
    Query : {
        users: async (parent, args, { dataSources }, info) => {
            return dataSources.bolGraphQlApi.getUsers();
        }
    },
    Mutation: {
        createUser: async(parent, args, { dataSources }, info) => {
            return dataSources.bolGraphQlApi.createUser(args);
        }
    }
}
const dataSources = () => ({ bolGraphQlApi: new BolDataSource() });
const server = new ApolloServer({ typeDefs, resolvers, dataSources  });
export default server.createHandler();

Apollo Datasource

import { DataSource } from "apollo-datasource";
import { Container, CosmosClient, SqlQuerySpec } from "@azure/cosmos";

//below values stored in local.settings.json file
const endpoint = process.env["COSMOS_DB_ENDPOINT"];
const key = process.env["COSMOS_DB_KEY"];
const containerId = process.env["COSMOS_CB_CONTAINER_ID"];
const databaseId = process.env["COSMOS_DB_DATABASE_ID"];
const cosmosConnectionString = process.env["COSMOS_DB_CONNECTION_STRING"];


export class BolDataSource extends DataSource {
  constructor() {
    super();
  }

  initCosmosDb = async (): Promise<Container> => {
    const cosmosClient = new CosmosClient({ endpoint, key });
    //const cosmosClient = new CosmosClient(cosmosConnectionString);
    const cosmosContainer = cosmosClient.database(databaseId).container(containerId);
    return cosmosContainer;
  }

  getUsers = async (parent, args) => {
    console.log('Get Users');
    const querySpec: SqlQuerySpec = {
      query: "SELECT * FROM c",
      parameters: []
    };
    const container = await this.initCosmosDb();
    const { resources: results } = await container.items.query(querySpec).fetchAll();
    console.log(results.toString);
    return results;
  };
}

export default BolDataSource;

Here is the output I get when I run the graphql api from Postman -

It says Status is 200 and below is the graphql error message -

{
    "errors": [
        {
            "message": "Invalid URL",
            "locations": [
                {
                    "line": 2,
                    "column": 3
                }
            ],
            "path": [
                "users"
            ],
            "extensions": {
                "code": "INTERNAL_SERVER_ERROR",
                "exception": {
                    "input": "undefined",
                    "code": "ERR_INVALID_URL",
                    "stacktrace": [
                        "TypeError [ERR_INVALID_URL]: Invalid URL",
                        "    at new NodeError (node:internal/errors:372:5)",
                        "    at URL.onParseError (node:internal/url:553:9)",
                        "    at new URL (node:internal/url:629:5)",
                        "    at checkURL (C:\\home\\site\\wwwroot\\node_modules\\@azure\\cosmos\\dist\\index.js:8227:12)",
                        "    at new CosmosClient (C:\\home\\site\\wwwroot\\node_modules\\@azure\\cosmos\\dist\\index.js:8881:26)",
                        "    at BolDataSource.<anonymous> (C:\\home\\site\\wwwroot\\dist\\data-sources\\models\\bol-datasource.js:25:34)",
                        "    at Generator.next (<anonymous>)",
                        "    at C:\\home\\site\\wwwroot\\dist\\data-sources\\models\\bol-datasource.js:8:71",
                        "    at new Promise (<anonymous>)",
                        "    at __awaiter (C:\\home\\site\\wwwroot\\dist\\data-sources\\models\\bol-datasource.js:4:12)"
                    ]
                }
            }
        }
    ],
    "data": null
}

This is where I got the function url from - enter image description here

Sumchans
  • 3,088
  • 6
  • 32
  • 59

1 Answers1

0

This was an issue of the application settings missing in Azure portal. I had the local.settings.json file setup with the Cosmos DB connection string, but the same was not copied to Azure function app settings during deployment. Not all the settings are copied over during deployment, there are some settings that needs to be done manually after deployment.

Sumchans
  • 3,088
  • 6
  • 32
  • 59