Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generated SDK is not correct #632

Open
1oglop1 opened this issue Jul 30, 2024 · 2 comments
Open

Generated SDK is not correct #632

1oglop1 opened this issue Jul 30, 2024 · 2 comments
Labels
status:waiting-for-triage An issue that is yet to be reviewed or assigned ToTriage

Comments

@1oglop1
Copy link

1oglop1 commented Jul 30, 2024

This is a follow-up on #479.

Originally we've discussed a validation of the input parameter for the method graphClient.applications.byApplicationId("")

* Provides operations to manage the collection of application entities.
* @param applicationId The unique identifier of application
* @returns {ApplicationItemRequestBuilder}
*/
byApplicationId(applicationId: string) : ApplicationItemRequestBuilder;

Now I think the method is straight-up wrong. Because the documentation string mentions a collection but the result should be a single item or error.
The problem is that this method does not call /applications/{application-id} | applications.application.GetApplication but instead queries the list method operationId: applications.application.ListApplication.

I've looked at the OA spec https://github.com/microsoftgraph/msgraph-metadata/blob/0ce6deaacf593d97bacecf9a2ebbcf5f6b199abe/openapi/v1.0/openapi.yaml and discovered several things:

  • The SDK methods have weird names or use the name of HTTP method, instead they should IMO use the name from of the operationId
    example:
// Original
const appRequest = graphClient.applications.byApplicationId("")
const application = await appRequest.get();  // 

// according to API spec
const appItem = graphClient.applications.GetApplicationByAppId("") // or GetApplication
  • Generated structure does not follow the docs which makes the SDK difficult to use.
  • It is not possible/simple to use item methods without creating an item. This required the developer to go through the hoops and null checks. (I think I saw several similar issues in kiota)
  // @microsoft/msgraph-sdk-applications/applications/item
  const appRequest: ApplicationItemRequestBuilder = graphClient.applications.byApplicationId("")
  const result = await appRequest.toDeleteRequestInformation();
  
  // easier would be something like this
  graphClient.applications.DeleteApplication({appId: "123"}) 

I think that AWS SDK v3 has much nicer patterns and it would be great if cloud SDKs could follow a similar interface.
https://github.com/aws/aws-sdk-js-v3

const { DynamoDBClient, ListTablesCommand } = require("@aws-sdk/client-dynamodb");

(async () => {
  const client = new DynamoDBClient({ region: "us-west-2" });
  const command = new ListTablesCommand({});
  try {
    const results = await client.send(command);
    console.log(results.TableNames.join("\n"));
  } catch (err) {
    console.error(err);
  }
})();

If I translate this to ms-graph, it may look like this:

const graphClient = createGraphServiceClient(requestAdapter);
// import {GetApplicationByAppId} from "@microsoft/msgraph-sdk-applications"
const getApplicationsCommand = new GetApplicationByAppId({id: 12})
const item = await graphClient.send(getApplicationsCommand)

I find this much more explicit than the current module augmentation.

declare module "@microsoft/msgraph-sdk" {
interface GraphServiceClient {
/**
* Provides operations to manage the applications singleton.
*/
get applications(): ApplicationsRequestBuilder;
}

@baywet
Copy link
Member

baywet commented Jul 30, 2024

Hi @1oglop1 ,
Thank you for opening this issue as a follow-up.
There is a bit of context here that might be useful for other readers.

First off, there has been a general confusion for the application between the object ID which is the ID property on Microsoft graph and the application ID which is the client ID. Those are two different properties and the API sometimes accepts one sometimes accepts the other. At this point this is historical and besides improving the documentation there is not much we can do to fix that.

Another aspect to the sdk is that the generation code segments of the fluent API closely map with the path segmentation of the rest API itself.
This is done this way to ensure we can support the large API surface of Microsoft graph which has over 20,000 operations.
The other reason why it's done this way is to reduce the mental burden of mapping one to another.
So while the AWS SDK might work in their context, we could not apply that at scale to the Microsoft graph SDK.

About the modular augmentation, the reason why we had to implement that arguably complex solution was to reduce the end bundle size of any application. Long story short, if you only use a couple of operations, you don't want the full API surface to be pulled into your runtime application bundle, which would negatively impact the performance of your application.

With this additional context, what's happening here causing the confusion between the list operation and the get operation is the fact that you're not providing an ID to the parameter. That compounds with the fact that the underlying parameters validation is not validating for the missing ID. Which also compounds with the different types of IDs issue I outlined earlier. And lastly, when the URL template gets expended or when the service reaches two slashes it returns the result of a list operation instead of a 404.

I believe in fixing the perimeter validation will already go a long way to clarifying the confusion. I'll go ahead and create an issue in the corresponding dependency repository.

@baywet
Copy link
Member

baywet commented Jul 30, 2024

Here is the related issue microsoft/kiota-typescript#1299

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:waiting-for-triage An issue that is yet to be reviewed or assigned ToTriage
Projects
None yet
Development

No branches or pull requests

2 participants