gopheracademy / congo

Conference Management Software for Conference Organizers
MIT License
108 stars 17 forks source link

Create basic REST framework #3

Open bketelsen opened 9 years ago

bketelsen commented 9 years ago

net/http for 100% modularity and compatibility with existing middleware, etc.

bketelsen commented 9 years ago

or something really simple like gin, etc. Lots to choose from, pick one that many can use.

bketelsen commented 9 years ago

Negroni

bketelsen commented 9 years ago

whoa - what about gokit??

eduncan911 commented 9 years ago

Gorilla mux? Love the sub-routing for API versioning.

bketelsen commented 9 years ago

gorilla mux is good, and fairly well accepted as the standard

timoreimann commented 9 years ago

also fits well with the project name / icon. :-)

bketelsen commented 9 years ago

indeed!

eduncan911 commented 9 years ago

Ha, didn't even think of that.

eduncan911 commented 9 years ago

I'll take this on to provide a basic framework.

Give me until Tuesday to submit a PR (setting up a new dev machine ATM - Arch isn't too quick to setup).

bketelsen commented 9 years ago

@eduncan911 OK I'll assign this to you. As for arch, that's why I keep my dotfiles on github, including scripts to install all the dev stuff. Because I have a terrible habit of wiping my dev machine once a month.

bketelsen commented 9 years ago

Keep GoKit in mind as you go, I'd like for this to be a nice example of how to use GoKit.

eduncan911 commented 9 years ago

I was just reading up on go-kit (https://github.com/go-kit/kit - GoKit is something else). And I've watched Peter's youtube video on it.

It's very similar to what I was building, a micro-services framework based on event-sourcing:

https://github.com/eduncan911/es

Mine's not ready yet. It does have some interesting patterns in it, such as auto-generated BDD-type tests, self-integrity checks (got a new end point? it would catch if there are no tests for each workflow), and event sourced. It focuses on exposing the API and ignoring the implementation details, and anything published on the bus creates unit tests. But, it's not done.

go-kit seems fairly complete and is in use. Let me prototype some stuff in go-kit first... Being only RPC and not flexible for others, is a concern for others that may want to contribute to this. E.g. there's no json in go-kit, that I can see yet. I could be completely wrong on that though. I see why according to Jason (the overhead of marshaling).

bketelsen commented 9 years ago

BTW - I always use the Antergos installer for Arch. So much quicker than the long way. Just FYI if you haven't seen it.

eduncan911 commented 9 years ago

I'm new to Arch (about a month in). I come from the C++ world, learning how it all works (complete with all the cursing and lost time figuring it all out). Once I got a good handle, I'll move onto the easy installers. :+1:

EDIT: Btw, scoll up. I just posted a message before your last.

bketelsen commented 9 years ago

GoKit allows you to create an endpoint and expose it as http/json, GRPC, and thrift all at once. I'll let you explore the rest. See the addsvc example app for an example of this.

bketelsen commented 9 years ago

you know what all of these are missing -- endpoint documentation. go-restful is the only one I know of that does limited swagger integration. Some auto-generated drop wizard style docs are greatly needed in the Go world.

00imvj00 commented 9 years ago

what about front end ? what are we going to use for front end ? react ? angular ?

ShawnMilo commented 9 years ago

@webgini: There's some conversation going on about that in #4.

mbrevoort commented 9 years ago

Regarding swagger, we've been using this library throughout all of our internal projects https://github.com/RobotsAndPencils/go-swaggerLite/blob/master/README.md

We tend to use Gorilla modules at R&P but liked this approach because it was framework agnostic.

bketelsen commented 9 years ago

System should be multi-tenant. A single instance of the application should support multiple Conferences each with multiple events

eduncan911 commented 9 years ago

How is this looking?

In keeping attendees multi-homed, I'm treating them like events...

# api versioning?
/api/v1/...  # url based
api-version: 2 # custom request header
Accept: application/vnd.congo.v1+json # custom accept (kind of like this way, non-intrusive)

# conferences
GET  /api/conferences
POST /api/conference # create
GET  /api/conference/{[0-9]+}
PUT  /api/conference/{[0-9]+} # update
DEL  /api/conference/{[0-9]+}
...

# conference's events
GET  /api/conference/{[0-9]+}/events
POST /api/conference/{[0-9]+}/event # create
GET  /api/conference/{[0-9]+}/event/{[0-9]+}
PUT  /api/conference/{[0-9]+}/event/{[0-9]+} # update
DEL  /api/conference/{[0-9]+}/event/{[0-9]+}
GET  /api/conference/{[0-9]+}/event/{[0-9]+}/attendees
...

# conference attendees (CRUD functions of attendees)
GET  /api/conference/{[0-9]+}/attendees
POST /api/conference/{[0-9]+}/attendee # create 
GET  /api/conference/{[0-9]+}/attendee/{[0-9]+}
PUT  /api/conference/{[0-9]+}/attendee/{[0-9]+} # update
DEL  /api/conference/{[0-9]+}/attendee/{[0-9]+}
GET  /api/conference/{[0-9]+}/attendee/{[0-9]+}/events
...

# attendee actions (e.g. add an attendee to an event)
GET  /api/conference/{[0-9]+}/attendee/{[0-9]+}/event/{[0-9]+} # attendee's event details
PUT  /api/conference/{[0-9]+}/attendee/{[0-9]+}/event/{[0-9]+} # join an event, with meta
DEL  /api/conference/{[0-9]+}/attendee/{[0-9]+}/event/{[0-9]+} # leave an event

If we prefer to use querystrings for things like actions, we can. Just opening for comment.

bketelsen commented 9 years ago

good! Can you change to use new entity names?
Series (GopherCon) Event (GopherCon 2015) Activity (Pre-Party on the 7th)

eduncan911 commented 9 years ago

In the url key? (Or combination or name abf url key)

I'd hesitate to do that in an api url as I believe utls shouldn't change (e.g. rename an even).

For frontend, absolutely.

eduncan911 commented 9 years ago

(I'll fix spelling when I get to my desk)

How about names in URLs as url keys, except for attendees an other mass named entities?

bketelsen commented 9 years ago

I mean in the routes

# series  == GopherCon
GET  /api/series

#  events (instance of a series, i.e. GopherCon 2015)
GET  /api/series/{[0-9]+}/events

# attendees
GET /api/series/{[0-9]+}/event/{[0-9]+}/attendees
bketelsen commented 9 years ago

So GET /api/series would return: 1, GopherCon 2, OSCON

GET /api/series/1/events would return 1, GopherCon 2015 2, GopherCon 2015

GET /api/series/2/events would return 1, OSCON 2015

GET /api/series/1/events/1 would return 1, Brian Ketelsen 2, Eric St. Martin

bketelsen commented 9 years ago

I think the level of tenancy needs to be adjusted so that it's clear we can host several SERIES, like GopherCon, OSCON, RubyConf, etc.

bketelsen commented 9 years ago

As for named parameters, I don't have a particular desire for them. ID's are fine. Consumers for the API will all be programmatic anyway.

eduncan911 commented 9 years ago
/api/series/1/event/5/speakers
1, GopherCon
5, GohperCon 2015

Got it.

eduncan911 commented 9 years ago

Far from a pull request, but here's my current go-kit organization. Wanted to mention this before spending much more time in this pattern to get a working setup for a PR.

"Modules" are what could be described as "services", following Rinat Abdullin's definitions: http://abdullin.com/happypancake/

(*)If so desired/gets complicated. For example, if the /attendees module wants to know that an event has been postponed, you either have to cross-post to all of these modules, or the pub-sub approach: an event is published to a common bus that all modules subscribe to.

Congo's folder structure is shaping up to be below. All "/folders" below are Go source paths relative to Congo's root project. This is the pattern I've been using for other projects utilizing Rinat's microservice approach. It basically uses a domain-language organization, where each /folder represents an aggregate or group of actions. The key difference is that these /folders can be considered stand-alone micro services, if one chooses to scale out that way in the future.

/host

/series /events /attendees /speakers ...

bketelsen commented 9 years ago

Very interesting! I am excited to see this layout. As for publishing "events", Kafka is king. Let's plan on a Go interface for all messaging and provide an initial implementation with channels. We can work on a later implementation with Kafka and/or NSQ.

eduncan911 commented 9 years ago

That's my thoughts exactly (the bus). Hum, I have a lot of this plumbing already in my /es package:

http://github.com/eduncan911/es

And I started dog-fooding it in a project I called facet, if you want to take a peek:

https://github.com/eduncan911/facet

It could really use a go-kit overhaul. For now, I'll just re-implement here so it can evolve here.