# Endpoints | Method | URL Pattern | Handler | Action | |--------|-----------------|---------------------|--------------------------------------| | GET | /v1/healthcheck | healthCheckHandler | Show application information | | GET | /v1/movies | listMoviesHandler | Show the details of all movies | | POST | /v1/movies | createMoviesHandler | Create a new movie | | GET | /v1/movies/:id | showMovieHandler | Show the details of a specific movie | | PUT | /v1/movies/:id | editMovieHandler | Edit the details of a specific movie | | DELETE | /v1/movies/:id | deleteMovieHandler | Delete a specific movie | # Installation ## Launch API `go run ./cmd/api` If you want, you can also verify that the command-line flags are working correctly by specifying alternative **port** and **env** values when starting the application. When you do this, you should see the contents of the log message change accordingly. For example : `go run ./cmd/api -port=3030 -env=production` **time=2025-10-10T11:08:00.000+02:00 level=INFO msg= "starting server" addr=:3030 env=production** ## Test endpoints `curl -i localhost:4000/v1/healthcheck` The *-i* flag in the command above instructs curl to display the HTTP response headers as well as the response body. ### Result HTTP/1.1 200 OK Date: Mon, 05 Apr 2021 17:46:14 GMT Content-Length: 58 Content-Type: text/plain; charset=utf-8 status: available environment: development version: 1.0.0 ## API Versioning There are two comon approaches to doing this : 1. By prefixing all URLs with your API version, like **/v1/healthcheck** or **/v2/healthcheck** 2. By using custom **Accept** and **Content-Type** headers on requests and responses to convey the API version, like **Accept: application/vnd.greenlight-v1** From an HTTP semantics point of view, using headers to convey the API version is the 'purer' approach. But from a user-experience point of view, using a URL prefix is arguably better. It makes it possible for developers to see which version of the API is being used at a glance, and it also means that the API can still be explored using a regular web browser (which is harder if custom headers are required). ## Additional Information ### How different Go Types are encoded The following table summarizes how different Go types are mapped to JSON data types during encoding : | Go type | JSON type | |---------------------------------------------------|----------------------------| | bool | JSON boolean | | string | JSON string | | int*, uint*, float*, rune | JSON number | | array, slice | JSON array | | struct, map | JSON object | | nil pointers, interface values, slices, maps, etc | JSON null | | chan, func, complex* | Not supported | | time.Time | RFC3339-format JSON string | | []byte | Base64-encoded JSON string | | The last two of these are special cases which deserve a bit more explanation : - Go **time.Time** values (which are actually a struct behind the scenes) will be encoded as a JSON string in RFC 3339 format like **"2020-11-08T06:27:59+01:00"**, rather than as a JSON object. - A **[]byte** slice will be encoded as a base64-encoded JSON string, rather than as a JSON array. So, for example, a byte slice of **[]byte{'h','e','l','l','o'}** would appear as **"aGVsbG8="** in the JSON output. The base64 encoding uses padding and the standard character set. A few other important things to mention : - Encoding of nested objects is supported. So, for example, if you have a slice of structs in Go that will encode to an *array of objects* in JSON. - Channels, functions and **complex** number types cannot be encoded. If you try to do so, you'll get a **json.UnsupportedTypeError** error at runtime. - Any pointer values will encode as *the value pointed to*.