data-api-builder
data-api-builder copied to clipboard
[Bug]: GraphQL request redirected to favicon.ico
What happened?
Navigated to https://localhost:5001
Console:
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Route matched with {action = "Find", controller = "Rest"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Find(System.String) on controller Azure.DataApiBuilder.Service.Controllers.RestController (Azure.DataApiBuilder.Service).
fail: Azure.DataApiBuilder.Service.Controllers.RestController[0]
02f4732e-ab4e-4f7b-acbb-d07f758a5384: GraphQL request redirected to favicon.ico.
fail: Azure.DataApiBuilder.Service.Controllers.RestController[0]
02f4732e-ab4e-4f7b-acbb-d07f758a5384: at Azure.DataApiBuilder.Service.Controllers.RestController.HandleOperation(String route, EntityActionOperation operationType)
info: Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor[1]
Executing JsonResult, writing value of type '<>f__AnonymousType0`1[[<>f__AnonymousType1`3[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Azure.DataApiBuilder.Service, Version=0.8.52.0, Culture=neutral, PublicKeyToken=null]]'.
Configuration:
{
"$schema": "https://github.com/Azure/data-api-builder/releases/download/v0.8.52/dab.draft.schema.json",
"data-source": {
"database-type": "mssql",
"connection-string": "@env('my-connection-string')"
},
"runtime": {
"rest": {
"enabled": true,
"path": "/api"
},
"graphql": {
"enabled": false
},
"host": {
"cors": {
"origins": [],
"allow-credentials": false
},
"authentication": {
"provider": "StaticWebApps"
},
"mode": "development"
}
},
"entities": {
"PageCustomers": {
"source": {
"object": "[dbo].[PageCustomers]",
"type": "stored-procedure",
"parameters": {
"PageSize": "",
"StartIndex": ""
}
},
"graphql": {
"enabled": false
},
"rest": {
"enabled": true
},
"permissions": [
{
"role": "anonymous",
"actions": [ "execute" ]
}
]
}
}
}
SQL schema:
CREATE PROCEDURE PageCustomers
@StartIndex INT = 1,
@PageSize INT
AS
BEGIN
SELECT [Id], [Name], [City], [State]
FROM Customers
ORDER BY Name
OFFSET (@StartIndex - 1) * @PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY;
END
CREATE TABLE Customers
(
Id INT PRIMARY KEY IDENTITY(1, 1)
, Name NVARCHAR(50) NULL
, City VARCHAR(MAX) NOT NULL
, State VARCHAR(50) NOT NULL DEFAULT 'CO'
, Location AS (City + ', ' + State) PERSISTED
, SpecialRank DECIMAL(18, 2) NOT NULL DEFAULT 0
)
Version
Microsoft.DataApiBuilder 0.8.52+c69925060e1942d28515b9c4b89ea24832da0c7c
What database are you using?
Azure SQL
What hosting model are you using?
Local (including CLI)
Which API approach are you accessing DAB through?
REST
Relevant log output
C:\Temp\dab>dab start
Information: Microsoft.DataApiBuilder 0.8.52+c69925060e1942d28515b9c4b89ea24832da0c7c
Information: Config not provided. Trying to get default config based on DAB_ENVIRONMENT...
Information: Environment variable DAB_ENVIRONMENT is (null)
Loading config file from dab-config.json.
Information: Loaded config file: dab-config.json
Information: Setting default minimum LogLevel: Debug for Development mode.
Starting the runtime engine...
Loading config file from dab-config.json.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
User profile is available. Using 'C:\Users\jerry\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Azure.DataApiBuilder.Core.Services.ISqlMetadataProvider[0]
PageCustomers path: /api/PageCustomers
dbug: Azure.DataApiBuilder.Core.Resolvers.IQueryExecutor[0]
Executing query:
SELECT name as result_field_name, TYPE_NAME(system_type_id) as result_type, is_nullable FROM sys.dm_exec_describe_first_result_set_for_object (OBJECT_ID('dbo.PageCustomers'), 0) WHERE is_hidden is not NULL AND is_hidden = 0
dbug: Azure.DataApiBuilder.Core.Services.ISqlMetadataProvider[0]
Logging primary key information for entity: PageCustomers.
info: Azure.DataApiBuilder.Core.Configurations.RuntimeConfigValidator[0]
Validating Relationship Section in Config...
info: Azure.DataApiBuilder.Service.Startup[0]
Successfully completed runtime initialization.
info: Microsoft.Hosting.Lifetime[14]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[14]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\Temp\dab
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/ - -
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
4dd1aa81-0cfa-42b6-bd61-b3b234ad3700: Request authentication state: Anonymous.
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
4dd1aa81-0cfa-42b6-bd61-b3b234ad3700: The request will be executed in the context of Anonymous role
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'Health checks'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Health checks'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/2 GET https://localhost:5001/ - - - 200 - text/plain 23.9130ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 GET https://localhost:5001/favicon.ico - -
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
b388e75c-ea75-41c8-8d20-e64151c27bcc: Request authentication state: Anonymous.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'Azure.DataApiBuilder.Service.Controllers.RestController.Find (Azure.DataApiBuilder.Service)'
dbug: Azure.DataApiBuilder.Core.AuthenticationHelpers.ClientRoleHeaderAuthenticationMiddleware[0]
b388e75c-ea75-41c8-8d20-e64151c27bcc: The request will be executed in the context of Anonymous role
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[3]
Route matched with {action = "Find", controller = "Rest"}. Executing controller action with signature System.Threading.Tasks.Task`1[Microsoft.AspNetCore.Mvc.IActionResult] Find(System.String) on controller Azure.DataApiBuilder.Service.Controllers.RestController (Azure.DataApiBuilder.Service).
fail: Azure.DataApiBuilder.Service.Controllers.RestController[0]
b388e75c-ea75-41c8-8d20-e64151c27bcc: GraphQL request redirected to favicon.ico.
fail: Azure.DataApiBuilder.Service.Controllers.RestController[0]
b388e75c-ea75-41c8-8d20-e64151c27bcc: at Azure.DataApiBuilder.Service.Controllers.RestController.HandleOperation(String route, EntityActionOperation operationType)
info: Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor[1]
Executing JsonResult, writing value of type '<>f__AnonymousType0`1[[<>f__AnonymousType1`3[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Azure.DataApiBuilder.Service, Version=0.8.52.0, Culture=neutral, PublicKeyToken=null]]'.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[2]
Executed action Azure.DataApiBuilder.Service.Controllers.RestController.Find (Azure.DataApiBuilder.Service) in 20.2691ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Azure.DataApiBuilder.Service.Controllers.RestController.Find (Azure.DataApiBuilder.Service)'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/2 GET https://localhost:5001/favicon.ico - - - 400 - application/json;+charset=utf-8 39.3177ms
info: Microsoft.Hosting.Lifetime[0]
Application is shutting down...
Code of Conduct
- [X] I agree to follow this project's Code of Conduct
There are two parts to this bug:
- Why doesn't it work?
- This error message is useless to the developer.
-
This error is emitted into the logs because a browser attempts to load a
favicon.ico
file to display in the browser tab. Since DAB is an API endpoint, this type of request isn't honored. As an API, DAB would respond to direct requests for resources instead of the many requests a browser may try to send. Here is a screenshot of loadinghttps://localhost:5001
in the browser: -
Agreed. We probably shouldn't return this error or should offer a way to mitigate.
Closing criteria:
- Change how DAB alerts/logs to failed favicon requests by disabling ASP.NET logs by default in
appsettings.json
in favor of DAB only displaying DAB specific logs. - DAB should not log favicon.ico requests as failures that imply something is wrong with DAB normal operation.
- DAB should return 404 Not Found and not 400 Bad request for favicon requests.
Context:
The following events are logged to the console for every favicon.ico request:
fail: Azure.DataApiBuilder.Service.Controllers.RestController[0] b388e75c-ea75-41c8-8d20-e64151c27bcc: GraphQL request redirected to favicon.ico. fail: Azure.DataApiBuilder.Service.Controllers.RestController[0] b388e75c-ea75-41c8-8d20-e64151c27bcc: at Azure.DataApiBuilder.Service.Controllers.RestController.HandleOperation(String route, EntityActionOperation operationType)
A favicon request is a valid and expected requests from a web browser. The DAB API endpoint has no file to return because it is not meant to be browser/user facing (no GUI). DAB is really only meant to be accessed directly within a browser when a developer is actively building a DAB solution.
Production deployed apps will use DAB behind the scenes with HTTP requests to the exposed API endpoints.
Moving to 1.1rc
to potentially clean up.