# Task: create an endpoint to list all the referrals a user has made
The app should be able to call `GET /waitlist/referrals` and get a list of all the referrals a user has made, *roughly* something like:
```
{
"referrals": 7
}
```
## How to create a new API endpoint
If you want to create an endpoint `/waitlist/referrals`, you need to figure out which service handles all the paths under `/waitlist`. You can look at `ingress/kube.yaml` to figure this out. (In this case it's `service.waitlist`.)
The most basic endpoint would look something like this (at `service.waitlist/http_server/get_waitlist_referrals.go`):
```
package http_server
import (
"net/http"
"github.com/umbermoney/buildthebank/libraries/errors"
"github.com/umbermoney/buildthebank/libraries/session"
"github.com/umbermoney/buildthebank/service.waitlist/dao"
)
type GETWaitlistReferralsResponse struct {
Referrals int `json:"referrals"`
}
func GETWaitlistReferrals(req *http.Request) (interface{}, *errors.Error) {
userID, err := session.GetAuthenticatedUserID(req)
if err != nil {
return nil, err
}
referralsCount, err := dao.CountReferralsByUser(userID)
if err != nil {
return nil, err
}
return GETWaitlistReferralsResponse{
Referrals: referralsCount,
}, nil
}
```
This function would need to be registered in `service.waitlist/http_server/server.go`, in order for it to serve the right path.
You need to implement a `dao` method that counts the number of referrals for a particular user.
It may be helpful to look at:
- https://www.db-fiddle.com/ (for testing out SQL queries)
- https://gorm.io/docs/connecting_to_the_database.html (to see how our ORM works, so you know how to query the database (you can use `db.Raw` to query the database with raw SQL if need be))
## How to test this endpoint locally
From within `~/src/github.com/umbermoney/buildthebank`:
```
./scripts/local/teardown.sh
./scripts/local/setup.sh
./scripts/local/locurl.sh GET service.waitlist /waitlist/referrals
```
## Glossary
**Endpoint**: A combination of an HTTP method and a path. An endpoint is something you can `curl` and get a response.
**Handler**: A function that handles a request - either an HTTP request from the outside world, or a GRPC request from another service. API handlers will live in an `http_server` directory, whereas GRPC handlers will live in an `rpc_server` directory.
## How local services work
We have a script at `scripts/local/setup.sh`. This lists every directory beginning with "service.", checks if it's a Go program (i.e. if it contains a file `main.go` at the root of the directory), then builds it. It then picks a random port, starts the service running at that port (by starting it with an environment variable `SERVICE_{WHATEVER}_API_PORT` and/or `SERVICE_{WHATEVER}_RPC_PORT` for the HTTP and GRPC servers respectively, if it has either or both) and writing those ports to a file called `/tmp/umber/local/.profile`.
### Errors with local services
**Connection refused**
This probably means the service was started but crashed immediately. The [stderr](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)) file stream, which normally would be printed to your terminal if you ran it with `go run`, is written to `/tmp/umber/local/service.user/stderr`, replacing `service.user` with whatever the service in question is.
**Authentication error**
Either you didn't supply the two headers `AgentUserID` and `AgentAuthToken`, or these were invalid. You *could* try to log in, but the login process is complicated (for good reason). It's probably easiest to create a new user, and store the `session` object returned in the JSON response. Then whenever you make a `curl` command to an endpoint that requires the user to be logged in, make sure it contains the headers. E.g.:
`curl -H "AgentUserID: user_abc" -H "AgentAuthToken: awlkdnawlkd" -X POST -d '{"foo": "bar"}' localhost:$SERVICE_USER_API_PORT/users/update`
We should have a neater way of doing this, but for now the easiest way is to manually edit the `scripts/local/locurl.sh` script to shove those headers in right after the word `curl`. It's early days!
## Resources
**Go in general**
- [Go By Example](https://gobyexample.com/)
- [Effective Go](https://golang.org/doc/effective_go.html)
**HTTP in general**
- [The HTTP protocol (Mozilla)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview)
**The command line in general**
- [Unix command line cheatsheet](http://www.mathcs.emory.edu/~valerie/courses/fall10/155/resources/unix_cheatsheet.html)
-