I got bored and did this. I have no shame. Yes it is extremely over-engineered. But when the time comes for an enterprise level, distributed, Phish setlist data solution with 100% code coverage we'll see who's laughing. So far it's mostly served as a way for me to learn some new technologies like Docker and GraphQL.
Some would ask "Why use gRPC for this?", I ask "Why not?".
This project is still very young so expect breaking changes. LOTS OF THEM.
Clone the repository
This assumes that you have git installed.
git clone git@github.com:jloom6/phishql.git
Bootstrap
This assumes that you have golang and dep installed.
cd phishql
make bootstrap
Shock and persuade my soul to ignite
This assumes that you get your ass handed to you everyday.
make test
Note: You may need to install protoc
Run everything in Docker
This assumes that you have Docker installed.
make run-hard
Call the REST API
This assumes that you have jq installed. You obviously don't need it but it makes everything look nice.
curl -XPOST -d '{}' $(docker-machine ip):8080/v1/shows | jq .
Congrats. You did it!
Swagger json can be found in here, just paste that into this swagger editor to see example HTTP requests. You can also use the proto file and give gRPC a try on port :9090!
Available Endpoints
I'll be more descriptive of the endpoints eventually, the swagger docs should be sufficient for now.
gRPC | HTTP | GraphQL |
---|---|---|
GetShows | /v1/shows | shows |
GetArtists | /v1/arists | artists |
GetSongs | /v1/songs | songs |
GetTags | /v1/tags | tags |
GetTours | /v1/tours | tours |
GetVenues | /v1/venues | venues |
Base Conditions
You can search for shows with basic conditions like this
curl -XPOST -d '{
"condition": {
"base": {
"year": 2019,
"month": 7,
"day": 14,
"day_of_week": 1,
"city": "East Troy",
"state": "WI",
"country": "USA",
"song": "Ruby Waves"
}
}
}' $(docker-machine ip):8080/v1/shows | jq .
The fields in the base condition are all "anded" together. If you leave the fields out of the request they are ignored in the query. The "day_of_week" field is indexed such that Sunday is 1, Monday is 2, ..., Saturday is 7.
Composable Conditions
You can compose the conditions using "and" and "or" as demonstrated below. The query is for shows that occurred in the state of NJ AND occurred on a Sunday OR Saturday
curl -XPOST -d '{
"condition": {
"and": {
"conditions": [
{
"base": {
"state": "NJ"
}
},
{
"or": {
"conditions": [
{
"base": {
"day_of_week": 1
}
},
{
"base": {
"day_of_week": 7
}
}
]
}
}
]
}
}
}' $(docker-machine ip):8080/v1/shows | jq .
If the entity model seems a bit... superfluous, that is because they are auto-generated from proto files using gRPC Gateway.
GraphQL
I implemented a GraphQL service for this because why not. Right now the only interesting query would be shows. FYI I'm not sure if the input syntax in my example is entirely correct given the circular dependency
input BaseCondition {
year: Int
month: Int
day: Int
dayOfWeek: Int
city: String
state: String
country: String
song: String
}
input Condition {
and: [Condition]
or: [Condition]
base: BaseCondition
}
An example query could look like this for shows in the state of NJ in 2019
{
shows(condition: {
and: [
{
base: {
year: 2019
}
},
{
base: {
state: "NJ"
}
}
]
}) {
date,
venue {
name,
city,
state,
country
},
tour {
name
},
sets {
label,
songs {
tag {
text
},
song {
name
},
transition
}
}
}
}
The example curl for the request would be this
curl -g "http://$(docker-machine ip):8420/graphql?query={shows(condition:{and:[{base:{year:2019}},{base:{state:\"NJ\"}}]}){date,venue{name,city,state,country},tour{name},sets{label,songs{tag{text},song{name},transition}}}}" | jq .
Your hands and feet are mangoes, you're gonna be a genius anyway.
- Email: John Loomis - jloom6@gmail.com