skip to Main Content

I’m trying to create a simple signup service using Ballerina and MongoDB (using MongoDB Compass version 7.0.11). However, I’m encountering several errors related to MongoDB integration with Ballerina. Specifically, I’m getting the following errors during compilation:

Incompatible types:

1.Error: expected ‘ballerinax/mongodb:5.0.0:Client’, found ‘(ballerinax/mongodb:5.0.0:Client|ballerinax/mongodb:5.0.0:DatabaseError|ballerinax/mongodb:5.0.0:ApplicationError|error)’
Action invocation as an expression not allowed:

2.Error: action invocation as an expression not allowed here
Invalid remote method call:

3.Error: invalid remote method call: expected a client object, but found ‘ballerina/http:2.12.1:Request’
Type mismatch errors:

4.Error: incompatible type for parameter ‘targetType’ with inferred typedesc value: expected ‘typedesc<record {| anydata…; |}>’, found ‘typedesc’
Error: incompatible types: expected ‘map’, found ‘json’
Undefined functions:

5.Error: undefined function ‘hasNext’ in type ‘stream<json,error>’
Error: undefined method ‘insert’ in object ‘ballerinax/mongodb:5.0.0:Collection’

This is my Code
Code

This is my Error
Error

This is my Folder Structure
Folder Structure

I am using MongoDB Compass, with the database hosted locally at localhost:27017. My goal is to create a simple signup system that inserts user data (username, password) into a MongoDB collection using Ballerina.

1.I updated the Ballerina.toml file to include the MongoDB dependency:
Update Ballerina.toml

2.Used check to handle potential errors when creating the MongoDB client and performing database operations, but I am still encountering the same errors.

I would like to know the correct approach for integrating MongoDB with Ballerina (Swan Lake Update 10) and understand how to fix the above compilation errors. Specifically, I want to successfully run a service that inserts signup data into MongoDB.

Ballerina Version:
Ballerina 2201.10.0 (Swan Lake Update 10)

MongoDB Version:
MongoDB Compass 7.0.11

2

Answers


  1. Following code resolve your issues

    import ballerina/http;
    import ballerinax/mongodb;
    import ballerina/log;
    
    type User record {
        string username;
        string password;
    };
    
    mongodb:Client mongoDb = check new ({
        connection: {
            serverAddress: {
                host: "localhost",
                port: 27017
            }
        }
    });
    
    service /signup on new http:Listener(8080) {
        mongodb:Database userDb;
        mongodb:Collection userCollection;
        function init() returns error? {
            self.userDb = check mongoDb->getDatabase("userDB");
            self.userCollection = check self.userDb->getCollection("userCollection");
        }
        resource function post signup(http:Caller caller, http:Request req) returns error? {
            // Parse the JSON payload from the request body
            json signuppayload = check req.getJsonPayload();
            User userDetails = check signuppayload.cloneWithType(User);
    
            // Check if the user already exists in the collection
            map<json> filter = {username: userDetails.username};
            stream<User, error?> userStream = check self.userCollection->find(filter);
            if (userStream.next() is record {| User value; |}) {
                log:printError("User already exists");
                http:Response conflictResponse = new;
                conflictResponse.setTextPayload("User already exists");
                check caller->respond(conflictResponse);
                return;
            }
    
            // Insert the new user into the MongoDB collection
            check self.userCollection->insertOne(userDetails);
    
            // send a sucess response
            http:Response response = new;
            response.setTextPayload("User signed up successfully");
            check caller->respond(response);
        }
    }
    

    These are the reasons for each error

    1. When initializing the client, the return type can be either mongodb:Client(when the client created sucessfully) or an error(when there is an error, while creating the client).
      https://github.com/ballerina-platform/module-ballerinax-mongodb/blob/76cdb7eca6c5ddb305df1d5350dc630137ffc2d0/ballerina/client.bal#L28

    2. Actions cannot be use declare module level variables

    • mongoDb->getDatabase("userDB") is a remote call, SO it is an action. One way to solve this issue is to declare the variable in the function scope.
    1. In Ballerina -> used to call remote functions. . use to call methods inside the class.
    2. Please refer to the definition of the find function
    1. The correct method is https://github.com/ballerina-platform/ballerina-lang/blob/4dbc2fb37d959d7654d873266b6f9ca14f8a1d10/langlib/lang.stream/src/main/ballerina/stream.bal#L71
    Login or Signup to reply.
  2. There are a number of issues as indicated by the compile-time errors.

    1. The first error at L12 is because the MongoDB client initialization can result in an error. You can use check to cause module initialization to fail in the case of an error.

      mongodb:Client mongoDb = check new ({
      

      Also see the check expression example.

    2. L22 and L23 – actions (using ->) are not allowed at module-level. This restriction is related to sequence diagrams generated for code. If you want it to happen at module initialization, you can move the calls to a module init function.

    3. getJsonPayload() is a normal method (non-remote/resource) on a normal object http:Request (non-client). The normal method call syntax needs to be used, rather than the remote method call action/resource access action. I.e., use . instead of ->.

      req.getJsonPayload()
      
    4. There are two errors here.

      i. The first error is because you’re using json where a subtype of record {} is expected, so a mapping type is expected here. Note that record {} or record {| anydata...; |} is the same as map<anydata>. The json type is a union which consists of map<json> (representing JSON objects), but also (), boolean, int, float, decimal, string, and json[]. So if you want to bind to JSON object, you have to use map<json>, rather than just json. Note that you have to use check or handle the error on the RHS appropriately since find can return an error value too.

      stream<map<json>, error?> usersStream = check usersCollection->find(filter);
      

      ii. Similarly, the second error is because the type of filter is json rather than map<json>, which is the expected type for the argument.

    5. Again, two errors.

      i. Streams do not have a hasNext function. You can use the next() function and check if the value is present instead.

      ii. There is no insert method on mongodb:Collection usersCollection. Did you mean to use insertOne or insertMany instead?

    API docs for ballerinax/mongodbhttps://central.ballerina.io/ballerinax/mongodb/5.0.0


    If you are not using it already, please note that using the Ballerina plugin on VS Code will help identify available operations easily (with completions and suggestions) and will help you identify and fix errors easily.

    It is also recommended to share code and error snippets rather than images when raising StackOverflow questions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search