Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotas da api e swagger #15

Open
felihenrique opened this issue May 10, 2017 · 14 comments
Open

Rotas da api e swagger #15

felihenrique opened this issue May 10, 2017 · 14 comments
Assignees

Comments

@felihenrique
Copy link
Contributor

felihenrique commented May 10, 2017

Para facilitar na implementação, creio que seria bom definirmos primeiramente quais rotas fazem o quê, seguindo o padrão: GET para obter informações, POST para criar um novo recurso, PUT para editar um recurso e DELETE para remover um recurso.
Ex:
GET /events?page=x&pagesize=x - Retorna lista de eventos. Alguns parametros podem ser passados na url para definir quais eventos retornar como: intervalo de datas, quantidade de eventos, inicio da seleção, etc..
GET /events/{id} - Retorna informações sobre um evento em específico.
POST /events/ - Cria um novo evento. O evento deve estar no corpo da request em forma de json.
PUT /events/{id} - Edita um evento existente. O evento editado deve estar no corpo da request em forma de json.
DELETE /events/{id} - Deleta um evento em específico.

Edit:
Precisa também colocar as possíveis respostas do servidor.

@rodrigondec
Copy link
Member

Um adendo sobre o:

POST /events/ - Cria um novo evento. O evento deve estar no corpo da request em forma de json.

Será enviado um arquivo também pelo post na criação do evento.

@rodrigondec
Copy link
Member

Outro adendo, sobre:

DELETE /events/{id} - Deleta um evento em específico.

A ação de deletar no nosso sitema irá apenas desabilitar o registro. Colocarei o campo 'active'/'enabled' nas entidades.

@felihenrique
Copy link
Contributor Author

Porque apenas desabilita?

@rodrigondec
Copy link
Member

É uma boa prática, foi sugerido por @davidcardoso-ti e discutido na última reunião. Nunca é bom deletar mesmo o registro. Pois se o delete tiver sido um erro humano ou não, pode ser revertido. E não perdemos um database de conhecimento.

@felihenrique
Copy link
Contributor Author

Em relação a enviar arquivo, é bom ter uma rota apenas para dar upload de arquivos no servidor e retornar a url que foi armazenado o arquivo. Essa url coloca no evento que vai mandar no POST, que é o que vai ser armazenado de fato no db.

@rodrigondec
Copy link
Member

Então isso ficará num controller do front. Forneceremos uma url pra registrar o evento e uma url pra registrar o arquivo. E o controller do front terá que chamar essas duas url, correto?

@felihenrique
Copy link
Contributor Author

Isso. Apos dar o upload do arquivo, o front coloca a url no json e faz a solicitação POST.

@felihenrique
Copy link
Contributor Author

Isso evitaria duplicações em outras coisas que precisarão enviar arquivos.

@rodrigondec
Copy link
Member

sim, verdade. Esqueci que arquivo não era mais acoplado a evento. Nice

@rodrigondec rodrigondec changed the title Definir rotas da api Rotas da api e swagger May 11, 2017
@rodrigondec
Copy link
Member

@felihenrique Se a gente deixar dessa forma sem a parametrização do id na url e utilizar a forma 'padrão' de get, ficando dessa forma a utilização da url
image

@rodrigondec
Copy link
Member

rodrigondec commented May 12, 2017

Outra coisa que eu vi, é utilizado um controler pra a entidade, e um controle pra lista de entidades, como no exemplo:

from flask.ext.restplus import Api, Resource, fields

app = Flask(__name__)
api = Api(app, version="1.0", title="Todo API",
    description="A simple TODO API extracted from the original flask-restful example",
)

ns = api.namespace("todos", description="TODO operations")

TODOS = {
    "todo1": {"task": "build an API"},
    "todo2": {"task": "?????"},
    "todo3": {"task": "profit!"},
}

todo = api.model("Todo", {
    "task": fields.String(required=True, description="The task details")
})

listed_todo = api.model("ListedTodo", {
    "id": fields.String(required=True, description="The todo ID"),
    "todo": fields.Nested(todo, description="The Todo")
})


def abort_if_todo_doesnt_exist(todo_id):
    if todo_id not in TODOS:
        api.abort(404, "Todo {} doesn"t exist".format(todo_id))

parser = api.parser()
parser.add_argument("task", type=str, required=True, help="The task details", location="form")


@ns.route("/<string:todo_id>")
@api.doc(responses={404: "Todo not found"}, params={"todo_id": "The Todo ID"})
class Todo(Resource):
    '''Show a single todo item and lets you delete them'''
    @api.doc(description="todo_id should be in {0}".format(", ".join(TODOS.keys())))
    @api.marshal_with(todo)
    def get(self, todo_id):
        '''Fetch a given resource'''
        abort_if_todo_doesnt_exist(todo_id)
        return TODOS[todo_id]

    @api.doc(responses={204: "Todo deleted"})
    def delete(self, todo_id):
        '''Delete a given resource'''
        abort_if_todo_doesnt_exist(todo_id)
        del TODOS[todo_id]
        return "", 204

    @api.doc(parser=parser)
    @api.marshal_with(todo)
    def put(self, todo_id):
        '''Update a given resource'''
        args = parser.parse_args()
        task = {"task": args["task"]}
        TODOS[todo_id] = task
        return task


@ns.route("/")
class TodoList(Resource):
    '''Shows a list of all todos, and lets you POST to add new tasks'''
    @api.marshal_list_with(listed_todo)
    def get(self):
        '''List all todos'''
        return [{"id": id, "todo": todo} for id, todo in TODOS.items()]

    @api.doc(parser=parser)
    @api.marshal_with(todo, code=201)
    def post(self):
        '''Create a todo'''
        args = parser.parse_args()
        todo_id = "todo%d" % (len(TODOS) + 1)
        TODOS[todo_id] = {"task": args["task"]}
        return TODOS[todo_id], 201


if __name__ == "__main__":
    app.run(debug=True)```

@felihenrique
Copy link
Contributor Author

felihenrique commented May 12, 2017

Não sei.. Acho que não precisa mudar, pq quando for passar outros parametros não vai ser passado o id.

Para lista é outro controller mesmo, pq cada classe só pode ter um método get, python não tem sobrecarga de funções :P

@felihenrique
Copy link
Contributor Author

No caso seguindo a logica desse codigo ai, poderia coloca para listar na classe EventPostController, e mudar o nome da classe.

@rodrigondec
Copy link
Member

Sim, gostei dessa segunda abordagem que coloquei ai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants