[SalesForce] Error: Too many DML statements: 1 AND Apex methods that are to be cached must be marked as @AuraEnabled(cacheable=true)

I have an AuraEnabled apex method which take a value and does a callout to get an Access Token and Refresh Token, stores them into Custom Settings and then returns true or false based on the outcome.

public static Boolean getAccessToken(String code) {
    try {
        if (String.isBlank(code)) {
            return false;
        }
        return OAuthService.getAccessToken(code);
    } catch (Exception cause) {
        throw AuraHandledExceptionFactory.create(cause);
    }
}

When the method is annotated with:

@AuraEnabled(cacheable=true)

I get this error:

Too many DML statements: 1

When the method is annotated with:

@AuraEnabled

I get this error:

Apex methods that are to be cached must be marked as @AuraEnabled(cacheable=true)

The Apex method is called by this JavaScript method

@wire(getAccessToken, { code: "$code" }) wiredAccessToken(result) {
    const { data, error } = result;
    if (data) {
        if (data === true) {
            showToast(this, "Success", "success", "success");
        }
    } else if (error) {
        this.handleError(error);
    }
}

and code is set here:

connectedCallback() {
    this.code = getUrlParamValue("namespace__code");
}

Questions

  1. What am I doing wrong here?
  2. Why am I stuck in a catch 22 situation?
  3. How do I fix this?

Best Answer

Wired invocation needs cacheable as true, but this causes the apex session to be read only.

To be able to perform DML you must not use cacheable which in turn means you cannot use a wire. Instead use imperative apex. Check the documentation.