endoflife-date / endoflife.date

Informative site with EoL dates of everything
https://endoflife.date
MIT License
2.44k stars 749 forks source link

:lady_beetle: Please return 404 when asking for non existing product from RESTful API call :pray: #2408

Closed adriens closed 1 year ago

adriens commented 1 year ago

:grey_question: Context/ steps to reproduce

Actually, the API is very useful to perform a lot of integrations :

For example, very useful to test if a product exist :

 http https://endoflife.date/api/maven.json
HTTP/1.1 200 OK
Accept-Ranges: bytes
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Age: 2
Cache-Control: public, max-age=0, must-revalidate
Content-Length: 420
Content-Type: application/json

:point_up: Yet, if I want to know more about a non-(yet)exsting product, I expected a HTTP 404, but got this instead :

http https://endoflife.date/api/jekyll.json

image

:dart: Feature request :pray:

:bookmark: Related issue

hugovk commented 1 year ago

It does return a 404 status code in the header. See the first line when calling with --headers:

$ http https://endoflife.date/api/jekyll.json --headers
HTTP/1.1 404 Not Found
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Age: 0
Cache-Control: public, max-age=0, must-revalidate
Content-Encoding: br
Content-Type: text/html; charset=utf-8
Date: Sun, 29 Jan 2023 21:55:22 GMT
Etag: 1585517765-ssl-df
Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), unload=(), window-placement=(), vertical-scroll=()
Referrer-Policy: strict-origin
Server: Netlify
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Nf-Request-Id: 01GQZRE6HR2S6HK9BQ2M2WHJ0C
X-Xss-Protection: 1; mode=block
adriens commented 1 year ago

:+1:

 http https://endoflife.date/api/jekyll.json --headers
HTTP/1.1 404 Not Found
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Age: 1745
Cache-Control: public, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Length: 1444
Content-Type: text/html; charset=utf-8
Date: Sun, 29 Jan 2023 21:39:05 GMT
Etag: 1585517765-ssl-df
Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), unload=(), window-placement=(), vertical-scroll=()
Referrer-Policy: strict-origin
Server: Netlify
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Nf-Request-Id: 01GQZS5MJPQ088CBWEQSYQV3CX
X-Xss-Protection: 1; mode=block
adriens commented 1 year ago

Would it possible to not get the html ?

captn3m0 commented 1 year ago

We can create an error.json file and setup a 404 under /api for the same.

https://docs.netlify.com/routing/redirects/redirect-options/#custom-404-page-handling

marcwrobel commented 1 year ago

Would it possible to not get the html ?

Why ?

adriens commented 1 year ago

@captn3m0

We can create an error.json file and setup a 404 under /api for the same.

That would look good :+1:

Would it possible to not get the html ?

Why ?

Very challenging question :smile_cat: For a more uniform user experience, for comfort I may say :thinking: Also getting the html makes it harder to eventually parse for a program.

" simplifies the error handling code on the client sid" cf image

So it could :

It could send back :

HTTP/1.1 400 Bad Request
    {
        "code": 404,
        "message": "This product does not exist on endoflife.date"
    }
adriens commented 1 year ago

:pray: @captn3m0 :clap:

http https://endoflife.date/api/rust.json
HTTP/1.1 404 Not Found
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 86400
Age: 0
Cache-Control: public, max-age=0, must-revalidate
Content-Length: 35
Content-Type: application/json
Date: Wed, 01 Feb 2023 20:22:31 GMT
Etag: "157871230d97d45464cc125ca0bc084f-ssl"
Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), unload=(), window-placement=(), vertical-scroll=()
Referrer-Policy: strict-origin
Server: Netlify
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-Nf-Request-Id: 01GR7AABH2XPBNVXE4RZ3K8HD4
X-Xss-Protection: 1; mode=block

{
    "message": "Product not found"
}
adriens commented 1 year ago

:clap: :pray: